changeset 29569:29a1f8fd8ee6

move idx_vector classes inside octave namespace * idx-vector.h, idx-vector.cc: Move idx_vector classes inside octave namespace. Update all uses outside of octave namespace to use octave:: tag. * Sparse.h: Eliminate forward declaration of idx_vector.
author John W. Eaton <jwe@octave.org>
date Wed, 28 Apr 2021 13:46:02 -0400
parents a7cbd0e54e7a
children 6d827dcde2b9
files examples/code/make_int.cc libinterp/corefcn/Cell.cc libinterp/corefcn/__ilu__.cc libinterp/corefcn/cellfun.cc libinterp/corefcn/data.cc libinterp/corefcn/fft.cc libinterp/corefcn/find.cc libinterp/corefcn/lookup.cc libinterp/corefcn/oct-map.cc libinterp/corefcn/oct-map.h libinterp/corefcn/pr-output.cc libinterp/corefcn/rand.cc libinterp/corefcn/sparse.cc libinterp/corefcn/sub2ind.cc libinterp/corefcn/utils.cc libinterp/octave-value/ov-base-diag.cc libinterp/octave-value/ov-base-diag.h libinterp/octave-value/ov-base-mat.cc libinterp/octave-value/ov-base-mat.h libinterp/octave-value/ov-base-sparse.cc libinterp/octave-value/ov-base.cc libinterp/octave-value/ov-base.h libinterp/octave-value/ov-bool-mat.h libinterp/octave-value/ov-bool-sparse.h libinterp/octave-value/ov-bool.h libinterp/octave-value/ov-ch-mat.cc libinterp/octave-value/ov-ch-mat.h libinterp/octave-value/ov-class.cc libinterp/octave-value/ov-class.h libinterp/octave-value/ov-colon.h libinterp/octave-value/ov-complex.cc libinterp/octave-value/ov-complex.h libinterp/octave-value/ov-float.h libinterp/octave-value/ov-flt-re-mat.h libinterp/octave-value/ov-intx.h libinterp/octave-value/ov-java.cc libinterp/octave-value/ov-lazy-idx.cc libinterp/octave-value/ov-lazy-idx.h libinterp/octave-value/ov-magic-int.cc libinterp/octave-value/ov-magic-int.h libinterp/octave-value/ov-perm.cc libinterp/octave-value/ov-perm.h libinterp/octave-value/ov-range.cc libinterp/octave-value/ov-range.h libinterp/octave-value/ov-re-diag.cc libinterp/octave-value/ov-re-mat.cc libinterp/octave-value/ov-re-mat.h libinterp/octave-value/ov-re-sparse.cc libinterp/octave-value/ov-re-sparse.h libinterp/octave-value/ov-scalar.h libinterp/octave-value/ov-str-mat.cc libinterp/octave-value/ov-struct.cc libinterp/octave-value/ov.cc libinterp/octave-value/ov.h libinterp/template-inst/Array-jit.cc libinterp/template-inst/Array-tc.cc liboctave/array/Array-C.cc liboctave/array/Array-b.cc liboctave/array/Array-ch.cc liboctave/array/Array-d.cc liboctave/array/Array-f.cc liboctave/array/Array-fC.cc liboctave/array/Array-i.cc liboctave/array/Array-idx-vec.cc liboctave/array/Array-s.cc liboctave/array/Array-str.cc liboctave/array/Array-util.cc liboctave/array/Array-util.h liboctave/array/Array-voidp.cc liboctave/array/Array.cc liboctave/array/Array.h liboctave/array/CMatrix.cc liboctave/array/CSparse.h liboctave/array/MArray.cc liboctave/array/MArray.h liboctave/array/MSparse.h liboctave/array/PermMatrix.cc liboctave/array/PermMatrix.h liboctave/array/Range.cc liboctave/array/Range.h liboctave/array/Sparse.cc liboctave/array/Sparse.h liboctave/array/boolSparse.cc liboctave/array/boolSparse.h liboctave/array/dMatrix.cc liboctave/array/dSparse.h liboctave/array/fCMatrix.cc liboctave/array/fMatrix.cc liboctave/array/idx-vector.cc liboctave/array/idx-vector.h liboctave/numeric/oct-convn.cc liboctave/operators/mx-op-defs.h
diffstat 92 files changed, 2375 insertions(+), 2392 deletions(-) [+]
line wrap: on
line diff
--- a/examples/code/make_int.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/examples/code/make_int.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -49,7 +49,8 @@
   void operator delete (void *p, size_t size);
 #endif
 
-  idx_vector index_vector (bool) const { return idx_vector ((double) scalar); }
+  octave::idx_vector index_vector (bool) const
+  { return octave::idx_vector ((double) scalar); }
 
   int rows (void) const { return 1; }
   int columns (void) const { return 1; }
--- a/libinterp/corefcn/Cell.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/Cell.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -191,7 +191,7 @@
 
         case 1:
           {
-            idx_vector i = idx_arg(0).index_vector ();
+            octave::idx_vector i = idx_arg(0).index_vector ();
 
             retval = Array<octave_value>::index (i, resize_ok, Matrix ());
           }
@@ -199,10 +199,10 @@
 
         case 2:
           {
-            idx_vector i = idx_arg(0).index_vector ();
+            octave::idx_vector i = idx_arg(0).index_vector ();
 
             k = 1;
-            idx_vector j = idx_arg(1).index_vector ();
+            octave::idx_vector j = idx_arg(1).index_vector ();
 
             retval = Array<octave_value>::index (i, j, resize_ok, Matrix ());
           }
@@ -210,7 +210,7 @@
 
         default:
           {
-            Array<idx_vector> iv (dim_vector (n, 1));
+            Array<octave::idx_vector> iv (dim_vector (n, 1));
 
             for (k = 0; k < n; k++)
               iv(k) = idx_arg(k).index_vector ();
@@ -245,7 +245,7 @@
 {
   octave_idx_type len = idx_arg.length ();
 
-  Array<idx_vector> ra_idx (dim_vector (len, 1));
+  Array<octave::idx_vector> ra_idx (dim_vector (len, 1));
 
   for (octave_idx_type i = 0; i < len; i++)
     {
@@ -270,7 +270,7 @@
 {
   octave_idx_type len = idx_arg.length ();
 
-  Array<idx_vector> ra_idx (dim_vector (len, 1));
+  Array<octave::idx_vector> ra_idx (dim_vector (len, 1));
 
   for (octave_idx_type i = 0; i < len; i++)
     try
--- a/libinterp/corefcn/__ilu__.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/__ilu__.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -892,7 +892,7 @@
     {
       U = U.transpose ();
       // The diagonal, conveniently permuted is added to U
-      U += diag.index (idx_vector::colon, perm_vec);
+      U += diag.index (octave::idx_vector::colon, perm_vec);
       L = L.transpose ();
     }
 }
@@ -938,8 +938,8 @@
           retval(0) = L + speye;
           if (nargout == 3)
             {
-              retval(1) = U.index (idx_vector::colon, perm);
-              retval(2) = speye.index (idx_vector::colon, perm);
+              retval(1) = U.index (octave::idx_vector::colon, perm);
+              retval(2) = speye.index (octave::idx_vector::colon, perm);
             }
           else
             retval(1) = U;
@@ -949,11 +949,11 @@
           retval(1) = U;
           if (nargout == 3)
             {
-              retval(0) = L.index (perm, idx_vector::colon) + speye;
-              retval(2) = speye.index (perm, idx_vector::colon);
+              retval(0) = L.index (perm, octave::idx_vector::colon) + speye;
+              retval(2) = speye.index (perm, octave::idx_vector::colon);
             }
           else
-            retval(0) = L + speye.index (idx_vector::colon, perm);
+            retval(0) = L + speye.index (octave::idx_vector::colon, perm);
         }
     }
   else
@@ -979,8 +979,8 @@
           retval(0) = L + speye;
           if (nargout == 3)
             {
-              retval(1) = U.index (idx_vector::colon, perm);
-              retval(2) = speye.index (idx_vector::colon, perm);
+              retval(1) = U.index (octave::idx_vector::colon, perm);
+              retval(2) = speye.index (octave::idx_vector::colon, perm);
             }
           else if (nargout == 2)
             retval(1) = U;
@@ -990,11 +990,11 @@
           retval(1) = U;
           if (nargout == 3)
             {
-              retval(0) = L.index (perm, idx_vector::colon) + speye;
-              retval(2) = speye.index (perm, idx_vector::colon);
+              retval(0) = L.index (perm, octave::idx_vector::colon) + speye;
+              retval(2) = speye.index (perm, octave::idx_vector::colon);
             }
           else
-            retval(0) = L + speye.index (idx_vector::colon, perm);
+            retval(0) = L + speye.index (octave::idx_vector::colon, perm);
         }
     }
 
--- a/libinterp/corefcn/cellfun.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/cellfun.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -1920,14 +1920,14 @@
 {
   octave_idx_type nidx = (idim < nd ? d[idim].numel () : 1);
   if (nidx == 1)
-    idx[0] = idx_vector::colon;
+    idx[0] = octave::idx_vector::colon;
   else
     {
       octave_idx_type l = 0;
       for (octave_idx_type i = 0; i < nidx; i++)
         {
           octave_idx_type u = l + d[idim](i);
-          idx[i] = idx_vector (l, u);
+          idx[i] = octave::idx_vector (l, u);
           l = u;
         }
     }
@@ -1965,17 +1965,17 @@
       for (octave_idx_type i = 0; i < nidx; i++)
         {
           octave_idx_type u = l + d[ivec](i);
-          retval.xelem (i) = a.index (idx_vector (l, u));
+          retval.xelem (i) = a.index (octave::idx_vector (l, u));
           l = u;
         }
     }
   else
     {
       // General 2D case.  Use 2D indexing.
-      OCTAVE_LOCAL_BUFFER (idx_vector, ridx, nridx);
+      OCTAVE_LOCAL_BUFFER (octave::idx_vector, ridx, nridx);
       prepare_idx (ridx, 0, nd, d);
 
-      OCTAVE_LOCAL_BUFFER (idx_vector, cidx, ncidx);
+      OCTAVE_LOCAL_BUFFER (octave::idx_vector, cidx, ncidx);
       prepare_idx (cidx, 1, nd, d);
 
       for (octave_idx_type j = 0; j < ncidx; j++)
@@ -2014,8 +2014,8 @@
 
   retval.clear (rdv);
 
-  OCTAVE_LOCAL_BUFFER (idx_vector, xidx, idxtot);
-  OCTAVE_LOCAL_BUFFER (idx_vector *, idx, nd);
+  OCTAVE_LOCAL_BUFFER (octave::idx_vector, xidx, idxtot);
+  OCTAVE_LOCAL_BUFFER (octave::idx_vector *, idx, nd);
 
   idxtot = 0;
   for (int i = 0; i < nd; i++)
@@ -2026,8 +2026,8 @@
     }
 
   OCTAVE_LOCAL_BUFFER_INIT (octave_idx_type, ridx, nd, 0);
-  Array<idx_vector> ra_idx
-    (dim_vector (1, std::max (nd, a.ndims ())), idx_vector::colon);
+  Array<octave::idx_vector> ra_idx
+    (dim_vector (1, std::max (nd, a.ndims ())), octave::idx_vector::colon);
 
   for (octave_idx_type j = 0; j < retval.numel (); j++)
     {
@@ -2300,7 +2300,7 @@
                             || (dim == 1 && array.rows () == 1)))
     {
       for (octave_idx_type i = 0; i < n; i++)
-        retval.xelem (i) = array.index (idx_vector (lb(i) - 1, ub(i)));
+        retval.xelem (i) = array.index (octave::idx_vector (lb(i) - 1, ub(i)));
     }
   else
     {
@@ -2310,11 +2310,11 @@
         dim = dv.first_non_singleton ();
       ndims = std::max (ndims, dim + 1);
 
-      Array<idx_vector> idx (dim_vector (ndims, 1), idx_vector::colon);
+      Array<octave::idx_vector> idx (dim_vector (ndims, 1), octave::idx_vector::colon);
 
       for (octave_idx_type i = 0; i < n; i++)
         {
-          idx(dim) = idx_vector (lb(i) - 1, ub(i));
+          idx(dim) = octave::idx_vector (lb(i) - 1, ub(i));
           retval.xelem (i) = array.index (idx);
         }
     }
--- a/libinterp/corefcn/data.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/data.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -6858,7 +6858,7 @@
       // NOTE: Can not change this to ovl() call because arg.sort changes sidx
       //       and objects are declared const in ovl prototype.
       retval(0) = arg.sort (sidx, dim, smode);
-      retval(1) = idx_vector (sidx, dv(dim));  // No checking, extent is known.
+      retval(1) = octave::idx_vector (sidx, dv(dim));  // No checking, extent is known.
     }
   else
     retval = ovl (arg.sort (dim, smode));
@@ -7284,7 +7284,7 @@
 
   try
     {
-      idx_vector n = args(1).index_vector ();
+      octave::idx_vector n = args(1).index_vector ();
 
       switch (argx.builtin_type ())
         {
@@ -7350,7 +7350,7 @@
 
 template <typename NDT>
 static NDT
-do_accumarray_sum (const idx_vector& idx, const NDT& vals,
+do_accumarray_sum (const octave::idx_vector& idx, const NDT& vals,
                    octave_idx_type n = -1)
 {
   typedef typename NDT::element_type T;
@@ -7389,7 +7389,7 @@
 
   try
     {
-      idx_vector idx = args(0).index_vector ();
+      octave::idx_vector idx = args(0).index_vector ();
       octave_idx_type n = -1;
       if (nargin == 3)
         n = args(2).idx_type_value (true);
@@ -7434,7 +7434,7 @@
 
 template <typename NDT>
 static NDT
-do_accumarray_minmax (const idx_vector& idx, const NDT& vals,
+do_accumarray_minmax (const octave::idx_vector& idx, const NDT& vals,
                       octave_idx_type n, bool ismin,
                       const typename NDT::element_type& zero_val)
 {
@@ -7447,7 +7447,7 @@
   NDT retval (dim_vector (n, 1), zero_val);
 
   // Pick minimizer or maximizer.
-  void (MArray<T>::*op) (const idx_vector&, const MArray<T>&)
+  void (MArray<T>::*op) (const octave::idx_vector&, const MArray<T>&)
     = ismin ? (&MArray<T>::idx_min) : (&MArray<T>::idx_max);
 
   octave_idx_type l = idx.length (n);
@@ -7477,7 +7477,7 @@
 
   try
     {
-      idx_vector idx = args(0).index_vector ();
+      octave::idx_vector idx = args(0).index_vector ();
       octave_idx_type n = -1;
       if (nargin == 4)
         n = args(3).idx_type_value (true);
@@ -7563,7 +7563,7 @@
 
 template <typename NDT>
 static NDT
-do_accumdim_sum (const idx_vector& idx, const NDT& vals,
+do_accumdim_sum (const octave::idx_vector& idx, const NDT& vals,
                  int dim = -1, octave_idx_type n = -1)
 {
   typedef typename NDT::element_type T;
@@ -7610,7 +7610,7 @@
 
   try
     {
-      idx_vector idx = args(0).index_vector ();
+      octave::idx_vector idx = args(0).index_vector ();
       int dim = -1;
       if (nargin >= 3)
         dim = args(2).int_value () - 1;
@@ -7832,7 +7832,7 @@
       octave_idx_type k = retval.columns ();
       while (order > 0 && k > 0)
         {
-          idx_vector col1 (':'), col2 (':'), sl1 (1, k), sl2 (0, k-1);
+          octave::idx_vector col1 (':'), col2 (':'), sl1 (1, k), sl2 (0, k-1);
           retval = SparseT (retval.index (col1, sl1))
                    - SparseT (retval.index (col2, sl2));
           assert (retval.columns () == k-1);
@@ -7845,7 +7845,7 @@
       octave_idx_type k = retval.rows ();
       while (order > 0 && k > 0)
         {
-          idx_vector col1 (':'), col2 (':'), sl1 (1, k), sl2 (0, k-1);
+          octave::idx_vector col1 (':'), col2 (':'), sl1 (1, k), sl2 (0, k-1);
           retval = SparseT (retval.index (sl1, col1))
                    - SparseT (retval.index (sl2, col2));
           assert (retval.rows () == k-1);
--- a/libinterp/corefcn/fft.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/fft.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -110,8 +110,8 @@
     {
       octave_value_list idx (ndims);
       for (octave_idx_type i = 0; i < ndims; i++)
-        idx(i) = idx_vector::colon;
-      idx(dim) = idx_vector (static_cast<octave_idx_type> (0));
+        idx(i) = octave::idx_vector::colon;
+      idx(dim) = octave::idx_vector (static_cast<octave_idx_type> (0));
 
       return arg.index_op (idx);
     }
--- a/libinterp/corefcn/find.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/find.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -58,7 +58,7 @@
     {
     default:
     case 3:
-      retval(2) = Array<T> (nda.index (idx_vector (idx)));
+      retval(2) = Array<T> (nda.index (octave::idx_vector (idx)));
       OCTAVE_FALLTHROUGH;
 
     case 2:
@@ -72,13 +72,13 @@
             idx.xelem (i) %= nr;
           }
         iext = -1;
-        retval(1) = idx_vector (jdx, -1);
+        retval(1) = octave::idx_vector (jdx, -1);
       }
       OCTAVE_FALLTHROUGH;
 
     case 1:
     case 0:
-      retval(0) = idx_vector (idx, iext);
+      retval(0) = octave::idx_vector (idx, iext);
       break;
     }
 
--- a/libinterp/corefcn/lookup.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/lookup.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -120,7 +120,7 @@
               idx.xelem (i) = std::max (zero, std::min (j, n-2));
             }
 
-          retval = idx_vector (idx);
+          retval = octave::idx_vector (idx);
         }
       else if (left_inf)
         {
@@ -132,7 +132,7 @@
               idx.xelem (i) = std::max (zero, j);
             }
 
-          retval = idx_vector (idx);
+          retval = octave::idx_vector (idx);
         }
       else if (right_inf)
         {
--- a/libinterp/corefcn/oct-map.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/oct-map.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -845,7 +845,7 @@
 */
 
 octave_map
-octave_map::index (const idx_vector& i, bool resize_ok) const
+octave_map::index (const octave::idx_vector& i, bool resize_ok) const
 {
   octave_map retval (xkeys);
   octave_idx_type nf = nfields ();
@@ -869,7 +869,7 @@
 }
 
 octave_map
-octave_map::index (const idx_vector& i, const idx_vector& j,
+octave_map::index (const octave::idx_vector& i, const octave::idx_vector& j,
                    bool resize_ok) const
 {
   octave_map retval (xkeys);
@@ -894,7 +894,7 @@
 }
 
 octave_map
-octave_map::index (const Array<idx_vector>& ia, bool resize_ok) const
+octave_map::index (const Array<octave::idx_vector>& ia, bool resize_ok) const
 {
   octave_map retval (xkeys);
   octave_idx_type nf = nfields ();
@@ -935,7 +935,7 @@
         {
         case 1:
           {
-            idx_vector i = idx(0).index_vector ();
+            octave::idx_vector i = idx(0).index_vector ();
 
             retval = index (i, resize_ok);
           }
@@ -943,10 +943,10 @@
 
         case 2:
           {
-            idx_vector i = idx(0).index_vector ();
+            octave::idx_vector i = idx(0).index_vector ();
 
             k = 1;
-            idx_vector j = idx(1).index_vector ();
+            octave::idx_vector j = idx(1).index_vector ();
 
             retval = index (i, j, resize_ok);
           }
@@ -954,7 +954,7 @@
 
         default:
           {
-            Array<idx_vector> ia (dim_vector (n_idx, 1));
+            Array<octave::idx_vector> ia (dim_vector (n_idx, 1));
 
             for (k = 0; k < n_idx; k++)
               ia(k) = idx(k).index_vector ();
@@ -978,20 +978,20 @@
 octave_map
 octave_map::column (octave_idx_type k) const
 {
-  return index (idx_vector::colon, k);
+  return index (octave::idx_vector::colon, k);
 }
 
 octave_map
 octave_map::page (octave_idx_type k) const
 {
-  static Array<idx_vector> ia (dim_vector (3, 1), idx_vector::colon);
+  static Array<octave::idx_vector> ia (dim_vector (3, 1), octave::idx_vector::colon);
 
   ia(2) = k;
   return index (ia);
 }
 
 void
-octave_map::assign (const idx_vector& i, const octave_map& rhs)
+octave_map::assign (const octave::idx_vector& i, const octave_map& rhs)
 {
   if (rhs.xkeys.is_same (xkeys))
     {
@@ -1038,7 +1038,7 @@
 }
 
 void
-octave_map::assign (const idx_vector& i, const idx_vector& j,
+octave_map::assign (const octave::idx_vector& i, const octave::idx_vector& j,
                     const octave_map& rhs)
 {
   if (rhs.xkeys.is_same (xkeys))
@@ -1086,7 +1086,7 @@
 }
 
 void
-octave_map::assign (const Array<idx_vector>& ia,
+octave_map::assign (const Array<octave::idx_vector>& ia,
                     const octave_map& rhs)
 {
   if (rhs.xkeys.is_same (xkeys))
@@ -1150,7 +1150,7 @@
         {
         case 1:
           {
-            idx_vector i = idx(0).index_vector ();
+            octave::idx_vector i = idx(0).index_vector ();
 
             assign (i, rhs);
           }
@@ -1158,10 +1158,10 @@
 
         case 2:
           {
-            idx_vector i = idx(0).index_vector ();
+            octave::idx_vector i = idx(0).index_vector ();
 
             k = 1;
-            idx_vector j = idx(1).index_vector ();
+            octave::idx_vector j = idx(1).index_vector ();
 
             assign (i, j, rhs);
           }
@@ -1169,7 +1169,7 @@
 
         default:
           {
-            Array<idx_vector> ia (dim_vector (n_idx, 1));
+            Array<octave::idx_vector> ia (dim_vector (n_idx, 1));
 
             for (k = 0; k < n_idx; k++)
               ia(k) = idx(k).index_vector ();
@@ -1226,7 +1226,7 @@
 */
 
 void
-octave_map::delete_elements (const idx_vector& i)
+octave_map::delete_elements (const octave::idx_vector& i)
 {
   octave_idx_type nf = nfields ();
   for (octave_idx_type k = 0; k < nf; k++)
@@ -1246,7 +1246,7 @@
 }
 
 void
-octave_map::delete_elements (int dim, const idx_vector& i)
+octave_map::delete_elements (int dim, const octave::idx_vector& i)
 {
   octave_idx_type nf = nfields ();
   for (octave_idx_type k = 0; k < nf; k++)
@@ -1266,7 +1266,7 @@
 }
 
 void
-octave_map::delete_elements (const Array<idx_vector>& ia)
+octave_map::delete_elements (const Array<octave::idx_vector>& ia)
 {
   octave_idx_type nf = nfields ();
   for (octave_idx_type k = 0; k < nf; k++)
@@ -1290,7 +1290,7 @@
 {
   octave_idx_type n_idx = idx.length ();
 
-  Array<idx_vector> ia (dim_vector (n_idx, 1));
+  Array<octave::idx_vector> ia (dim_vector (n_idx, 1));
 
   for (octave_idx_type i = 0; i < n_idx; i++)
     {
--- a/libinterp/corefcn/oct-map.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/oct-map.h	Wed Apr 28 13:46:02 2021 -0400
@@ -443,12 +443,12 @@
   static octave_map
   cat (int dim, octave_idx_type n, const octave_map *map_list);
 
-  octave_map index (const idx_vector& i, bool resize_ok = false) const;
+  octave_map index (const octave::idx_vector& i, bool resize_ok = false) const;
 
-  octave_map index (const idx_vector& i, const idx_vector& j,
+  octave_map index (const octave::idx_vector& i, const octave::idx_vector& j,
                     bool resize_ok = false) const;
 
-  octave_map index (const Array<idx_vector>& ia,
+  octave_map index (const Array<octave::idx_vector>& ia,
                     bool resize_ok = false) const;
 
   octave_map index (const octave_value_list&, bool resize_ok = false) const;
@@ -456,22 +456,23 @@
   octave_map column (octave_idx_type k) const;
   octave_map page (octave_idx_type k) const;
 
-  void assign (const idx_vector& i, const octave_map& rhs);
+  void assign (const octave::idx_vector& i, const octave_map& rhs);
 
-  void assign (const idx_vector& i, const idx_vector& j, const octave_map& rhs);
+  void assign (const octave::idx_vector& i, const octave::idx_vector& j,
+               const octave_map& rhs);
 
-  void assign (const Array<idx_vector>& ia, const octave_map& rhs);
+  void assign (const Array<octave::idx_vector>& ia, const octave_map& rhs);
 
   void assign (const octave_value_list&, const octave_map& rhs);
 
   void assign (const octave_value_list& idx, const std::string& k,
                const Cell& rhs);
 
-  void delete_elements (const idx_vector& i);
+  void delete_elements (const octave::idx_vector& i);
 
-  void delete_elements (int dim, const idx_vector& i);
+  void delete_elements (int dim, const octave::idx_vector& i);
 
-  void delete_elements (const Array<idx_vector>& ia);
+  void delete_elements (const Array<octave::idx_vector>& ia);
 
   void delete_elements (const octave_value_list&);
 
--- a/libinterp/corefcn/pr-output.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/pr-output.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -2161,13 +2161,13 @@
               nm += buf.str ();
             }
 
-          Array<idx_vector> idx (dim_vector (ndims, 1));
-
-          idx(0) = idx_vector (':');
-          idx(1) = idx_vector (':');
+          Array<octave::idx_vector> idx (dim_vector (ndims, 1));
+
+          idx(0) = octave::idx_vector (':');
+          idx(1) = octave::idx_vector (':');
 
           for (int k = 2; k < ndims; k++)
-            idx(k) = idx_vector (ra_idx(k));
+            idx(k) = octave::idx_vector (ra_idx(k));
 
           octave_value page
             = MAT_T (Array<ELT_T> (nda.index (idx), dim_vector (nr, nc)));
@@ -2746,13 +2746,13 @@
               nm += buf.str ();
             }
 
-          Array<idx_vector> idx (dim_vector (ndims, 1));
-
-          idx(0) = idx_vector (':');
-          idx(1) = idx_vector (':');
+          Array<octave::idx_vector> idx (dim_vector (ndims, 1));
+
+          idx(0) = octave::idx_vector (':');
+          idx(1) = octave::idx_vector (':');
 
           for (int k = 2; k < ndims; k++)
-            idx(k) = idx_vector (ra_idx(k));
+            idx(k) = octave::idx_vector (ra_idx(k));
 
           Array<std::string> page (nda.index (idx), dim_vector (nr, nc));
 
@@ -2988,13 +2988,13 @@
                 os << "\n";
             }
 
-          Array<idx_vector> idx (dim_vector (ndims, 1));
-
-          idx(0) = idx_vector (':');
-          idx(1) = idx_vector (':');
+          Array<octave::idx_vector> idx (dim_vector (ndims, 1));
+
+          idx(0) = octave::idx_vector (':');
+          idx(1) = octave::idx_vector (':');
 
           for (int k = 2; k < ndims; k++)
-            idx(k) = idx_vector (ra_idx(k));
+            idx(k) = octave::idx_vector (ra_idx(k));
 
           Array<T> page (nda.index (idx), dim_vector (nr, nc));
 
@@ -3096,13 +3096,13 @@
                 os << "\n";
             }
 
-          Array<idx_vector> idx (dim_vector (ndims, 1));
-
-          idx(0) = idx_vector (':');
-          idx(1) = idx_vector (':');
+          Array<octave::idx_vector> idx (dim_vector (ndims, 1));
+
+          idx(0) = octave::idx_vector (':');
+          idx(1) = octave::idx_vector (':');
 
           for (int k = 2; k < ndims; k++)
-            idx(k) = idx_vector (ra_idx(k));
+            idx(k) = octave::idx_vector (ra_idx(k));
 
           Array<T> page (nda.index (idx), dim_vector (nr, nc));
 
--- a/libinterp/corefcn/rand.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/rand.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -1202,8 +1202,8 @@
   if (m < n)
     idx.resize (dim_vector (1, m));
 
-  // Now create an array object with a cached idx_vector.
-  return ovl (new octave_matrix (r, idx_vector (idx)));
+  // Now create an array object with a cached octave::idx_vector.
+  return ovl (new octave_matrix (r, octave::idx_vector (idx)));
 }
 
 /*
--- a/libinterp/corefcn/sparse.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/sparse.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -214,9 +214,9 @@
       int k = 0;    // index we're checking when index_vector throws
       try
         {
-          idx_vector i = args(0).index_vector ();
+          octave::idx_vector i = args(0).index_vector ();
           k = 1;
-          idx_vector j = args(1).index_vector ();
+          octave::idx_vector j = args(1).index_vector ();
 
           if (args(2).islogical ())
             retval = SparseBoolMatrix (args(2).bool_array_value (), i,j,
--- a/libinterp/corefcn/sub2ind.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/sub2ind.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -116,7 +116,7 @@
 
   dim_vector dv = get_dim_vector (args(0), "sub2ind");
 
-  Array<idx_vector> idxa (dim_vector (nargin-1, 1));
+  Array<octave::idx_vector> idxa (dim_vector (nargin-1, 1));
 
   for (int j = 0; j < nargin - 1; j++)
     {
--- a/libinterp/corefcn/utils.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/corefcn/utils.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -1677,7 +1677,7 @@
 
   try
     {
-      idx_vector idx = args(0).index_vector (true);
+      octave::idx_vector idx = args(0).index_vector (true);
 
       if (nargin == 2)
         retval = idx.extent (n) <= n;
--- a/libinterp/octave-value/ov-base-diag.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-base-diag.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -110,9 +110,9 @@
       int k = 0;        // index we're accessing when index_vector throws
       try
         {
-          idx_vector idx0 = idx(0).index_vector ();
+          octave::idx_vector idx0 = idx(0).index_vector ();
           k = 1;
-          idx_vector idx1 = idx(1).index_vector ();
+          octave::idx_vector idx1 = idx(1).index_vector ();
 
           if (idx0.is_scalar () && idx1.is_scalar ())
             {
@@ -180,12 +180,12 @@
             int k = 0;
             try
               {
-                idx_vector ind = jdx(0).index_vector ();
+                octave::idx_vector ind = jdx(0).index_vector ();
                 k = 1;
                 dim_vector dv (matrix.rows (), matrix.cols ());
-                Array<idx_vector> ivec = ind2sub (dv, ind);
-                idx_vector i0 = ivec(0);
-                idx_vector i1 = ivec(1);
+                Array<octave::idx_vector> ivec = ind2sub (dv, ind);
+                octave::idx_vector i0 = ivec(0);
+                octave::idx_vector i1 = ivec(1);
 
                 if (i0(0) == i1(0)
                     && chk_valid_scalar (rhs, val))
@@ -211,9 +211,9 @@
             int k = 0;
             try
               {
-                idx_vector i0 = jdx(0).index_vector ();
+                octave::idx_vector i0 = jdx(0).index_vector ();
                 k = 1;
-                idx_vector i1 = jdx(1).index_vector ();
+                octave::idx_vector i1 = jdx(1).index_vector ();
                 if (i0(0) == i1(0)
                     && i0(0) < matrix.rows () && i1(0) < matrix.cols ()
                     && chk_valid_scalar (rhs, val))
@@ -456,7 +456,7 @@
 }
 
 template <typename DMT, typename MT>
-idx_vector
+octave::idx_vector
 octave_base_diag<DMT, MT>::index_vector (bool require_integers) const
 {
   return to_dense ().index_vector (require_integers);
--- a/libinterp/octave-value/ov-base-diag.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-base-diag.h	Wed Apr 28 13:46:02 2021 -0400
@@ -155,7 +155,7 @@
   double scalar_value (bool frc_str_conv = false) const
   { return double_value (frc_str_conv); }
 
-  OCTINTERP_API idx_vector
+  OCTINTERP_API octave::idx_vector
   index_vector (bool /* require_integers */ = false) const;
 
   OCTINTERP_API Matrix matrix_value (bool = false) const;
--- a/libinterp/octave-value/ov-base-mat.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-base-mat.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -157,7 +157,7 @@
 
         case 1:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             // optimize single scalar index.
             if (! resize_ok && i.is_scalar ())
@@ -169,10 +169,10 @@
 
         case 2:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             k=1;
-            idx_vector j = idx (1).index_vector ();
+            octave::idx_vector j = idx (1).index_vector ();
 
             // optimize two scalar indices.
             if (! resize_ok && i.is_scalar () && j.is_scalar ())
@@ -184,7 +184,7 @@
 
         default:
           {
-            Array<idx_vector> idx_vec (dim_vector (n_idx, 1));
+            Array<octave::idx_vector> idx_vec (dim_vector (n_idx, 1));
             bool scalar_opt = n_idx == nd && ! resize_ok;
             const dim_vector dv = matrix.dims ();
 
@@ -242,7 +242,7 @@
 
         case 1:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             matrix.assign (i, rhs);
           }
@@ -250,10 +250,10 @@
 
         case 2:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             k = 1;
-            idx_vector j = idx (1).index_vector ();
+            octave::idx_vector j = idx (1).index_vector ();
 
             matrix.assign (i, j, rhs);
           }
@@ -261,7 +261,7 @@
 
         default:
           {
-            Array<idx_vector> idx_vec (dim_vector (n_idx, 1));
+            Array<octave::idx_vector> idx_vec (dim_vector (n_idx, 1));
 
             for (k = 0; k < n_idx; k++)
               idx_vec(k) = idx(k).index_vector ();
@@ -318,7 +318,7 @@
 
         case 1:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             // optimize single scalar index.
             if (i.is_scalar () && i(0) < matrix.numel ())
@@ -330,10 +330,10 @@
 
         case 2:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             k = 1;
-            idx_vector j = idx (1).index_vector ();
+            octave::idx_vector j = idx (1).index_vector ();
 
             // optimize two scalar indices.
             if (i.is_scalar () && j.is_scalar () && nd == 2
@@ -346,7 +346,7 @@
 
         default:
           {
-            Array<idx_vector> idx_vec (dim_vector (n_idx, 1));
+            Array<octave::idx_vector> idx_vec (dim_vector (n_idx, 1));
             bool scalar_opt = n_idx == nd;
             const dim_vector dv = matrix.dims ().redim (n_idx);
 
@@ -394,7 +394,7 @@
 {
   octave_idx_type len = idx.length ();
 
-  Array<idx_vector> ra_idx (dim_vector (len, 1));
+  Array<octave::idx_vector> ra_idx (dim_vector (len, 1));
 
   for (octave_idx_type i = 0; i < len; i++)
     ra_idx(i) = idx(i).index_vector ();
--- a/libinterp/octave-value/ov-base-mat.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-base-mat.h	Wed Apr 28 13:46:02 2021 -0400
@@ -67,7 +67,7 @@
   octave_base_matrix (const octave_base_matrix& m)
     : octave_base_value (), matrix (m.matrix),
       typ (m.typ ? new MatrixType (*m.typ) : nullptr),
-      idx_cache (m.idx_cache ? new idx_vector (*m.idx_cache) : nullptr)
+      idx_cache (m.idx_cache ? new octave::idx_vector (*m.idx_cache) : nullptr)
   { }
 
   ~octave_base_matrix (void) { clear_cached_info (); }
@@ -202,10 +202,10 @@
 
   MT matrix;
 
-  idx_vector set_idx_cache (const idx_vector& idx) const
+  octave::idx_vector set_idx_cache (const octave::idx_vector& idx) const
   {
     delete idx_cache;
-    idx_cache = (idx ? new idx_vector (idx) : nullptr);
+    idx_cache = (idx ? new octave::idx_vector (idx) : nullptr);
     return idx;
   }
 
@@ -216,7 +216,7 @@
   }
 
   mutable MatrixType *typ;
-  mutable idx_vector *idx_cache;
+  mutable octave::idx_vector *idx_cache;
 
 private:
 
--- a/libinterp/octave-value/ov-base-sparse.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-base-sparse.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -75,7 +75,7 @@
 
         case 1:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             retval = octave_value (matrix.index (i, resize_ok));
           }
@@ -83,10 +83,10 @@
 
         case 2:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             k = 1;
-            idx_vector j = idx (1).index_vector ();
+            octave::idx_vector j = idx (1).index_vector ();
 
             retval = octave_value (matrix.index (i, j, resize_ok));
           }
@@ -198,7 +198,7 @@
         {
         case 1:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             matrix.assign (i, rhs);
 
@@ -207,10 +207,10 @@
 
         case 2:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             k = 1;
-            idx_vector j = idx (1).index_vector ();
+            octave::idx_vector j = idx (1).index_vector ();
 
             matrix.assign (i, j, rhs);
 
@@ -250,7 +250,7 @@
         {
         case 1:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             matrix.delete_elements (i);
 
@@ -259,10 +259,10 @@
 
         case 2:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             k = 1;
-            idx_vector j = idx (1).index_vector ();
+            octave::idx_vector j = idx (1).index_vector ();
 
             matrix.delete_elements (i, j);
 
--- a/libinterp/octave-value/ov-base.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-base.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -229,7 +229,7 @@
   error ("can't perform indexing operations for %s type", nm.c_str ());
 }
 
-idx_vector
+octave::idx_vector
 octave_base_value::index_vector (bool /* require_integers */) const
 {
   std::string nm = '<' + type_name () + '>';
--- a/libinterp/octave-value/ov-base.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-base.h	Wed Apr 28 13:46:02 2021 -0400
@@ -340,7 +340,7 @@
                   const std::list<octave_value_list>& idx,
                   const octave_value& rhs);
 
-  virtual idx_vector index_vector (bool require_integers = false) const;
+  virtual octave::idx_vector index_vector (bool require_integers = false) const;
 
   virtual dim_vector dims (void) const { return dim_vector (); }
 
--- a/libinterp/octave-value/ov-bool-mat.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-bool-mat.h	Wed Apr 28 13:46:02 2021 -0400
@@ -68,7 +68,7 @@
   octave_bool_matrix (const boolMatrix& bm, const MatrixType& t)
     : octave_base_matrix<boolNDArray> (bm, t) { }
 
-  octave_bool_matrix (const boolNDArray& bm, const idx_vector& cache)
+  octave_bool_matrix (const boolNDArray& bm, const octave::idx_vector& cache)
     : octave_base_matrix<boolNDArray> (bm)
   {
     set_idx_cache (cache);
@@ -89,9 +89,9 @@
 
   octave_base_value * try_narrowing_conversion (void);
 
-  idx_vector index_vector (bool /* require_integers */ = false) const
+  octave::idx_vector index_vector (bool /* require_integers */ = false) const
   {
-    return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix));
+    return idx_cache ? *idx_cache : set_idx_cache (octave::idx_vector (matrix));
   }
 
   builtin_type_t builtin_type (void) const { return btyp_bool; }
--- a/libinterp/octave-value/ov-bool-sparse.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-bool-sparse.h	Wed Apr 28 13:46:02 2021 -0400
@@ -87,9 +87,9 @@
   octave_base_value * try_narrowing_conversion (void);
 
   // FIXME: Adapt idx_vector to allow sparse logical indexing without overflow!
-  idx_vector index_vector (bool /* require_integers */ = false) const
+  octave::idx_vector index_vector (bool /* require_integers */ = false) const
   {
-    return idx_vector (matrix);
+    return octave::idx_vector (matrix);
   }
 
   builtin_type_t builtin_type (void) const { return btyp_bool; }
--- a/libinterp/octave-value/ov-bool.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-bool.h	Wed Apr 28 13:46:02 2021 -0400
@@ -74,7 +74,8 @@
   octave_value do_index_op (const octave_value_list& idx,
                             bool resize_ok = false);
 
-  idx_vector index_vector (bool /* require_integers */ = false) const { return idx_vector (scalar); }
+  octave::idx_vector index_vector (bool /* require_integers */ = false) const
+  { return octave::idx_vector (scalar); }
 
   builtin_type_t builtin_type (void) const { return btyp_bool; }
 
--- a/libinterp/octave-value/ov-ch-mat.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-ch-mat.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -57,14 +57,14 @@
 
 template class octave_base_matrix<charNDArray>;
 
-idx_vector
+octave::idx_vector
 octave_char_matrix::index_vector (bool /* require_integers */) const
 {
   const char *p = matrix.data ();
   if (numel () == 1 && *p == ':')
-    return idx_vector (':');
+    return octave::idx_vector (':');
   else
-    return idx_vector (array_value (true));
+    return octave::idx_vector (array_value (true));
 }
 
 double
--- a/libinterp/octave-value/ov-ch-mat.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-ch-mat.h	Wed Apr 28 13:46:02 2021 -0400
@@ -89,7 +89,7 @@
   octave_base_value * empty_clone (void) const
   { return new octave_char_matrix (); }
 
-  idx_vector index_vector (bool require_integers = false) const;
+  octave::idx_vector index_vector (bool require_integers = false) const;
 
   builtin_type_t builtin_type (void) const { return btyp_char; }
 
--- a/libinterp/octave-value/ov-class.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-class.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -825,7 +825,7 @@
   return retval;
 }
 
-idx_vector
+octave::idx_vector
 octave_class::index_vector (bool require_integers) const
 {
   octave::symbol_table& symtab
--- a/libinterp/octave-value/ov-class.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-class.h	Wed Apr 28 13:46:02 2021 -0400
@@ -127,7 +127,8 @@
                   const std::list<octave_value_list>& idx,
                   const octave_value& rhs);
 
-  OCTINTERP_API idx_vector index_vector (bool require_integers = false) const;
+  OCTINTERP_API octave::idx_vector
+  index_vector (bool require_integers = false) const;
 
   dim_vector dims (void) const { return m_map.dims (); }
 
--- a/libinterp/octave-value/ov-colon.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-colon.h	Wed Apr 28 13:46:02 2021 -0400
@@ -62,7 +62,8 @@
   octave_base_value * empty_clone (void) const
   { return new octave_magic_colon (); }
 
-  idx_vector index_vector (bool /* require_integers */ = false) const { return idx_vector (':'); }
+  octave::idx_vector index_vector (bool /* require_integers */ = false) const
+  { return octave::idx_vector (':'); }
 
   bool is_defined (void) const { return true; }
 
--- a/libinterp/octave-value/ov-complex.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-complex.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -144,7 +144,7 @@
 }
 
 // Can't make an index_vector from a complex number.  Throw an error.
-idx_vector
+octave::idx_vector
 octave_complex::index_vector (bool) const
 {
   std::ostringstream buf;
--- a/libinterp/octave-value/ov-complex.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-complex.h	Wed Apr 28 13:46:02 2021 -0400
@@ -82,7 +82,7 @@
                             bool resize_ok = false);
 
   // Use this to give a more specific error message.
-  idx_vector index_vector (bool /* require_integers */ = false) const;
+  octave::idx_vector index_vector (bool /* require_integers */ = false) const;
 
   octave_value any (int = 0) const
   {
--- a/libinterp/octave-value/ov-float.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-float.h	Wed Apr 28 13:46:02 2021 -0400
@@ -79,7 +79,8 @@
   octave_value do_index_op (const octave_value_list& idx,
                             bool resize_ok = false);
 
-  idx_vector index_vector (bool /* require_integers */ = false) const { return idx_vector (scalar); }
+  octave::idx_vector index_vector (bool /* require_integers */ = false) const
+  { return octave::idx_vector (scalar); }
 
   octave_value any (int = 0) const
   { return (scalar != 0 && ! lo_ieee_isnan (scalar)); }
--- a/libinterp/octave-value/ov-flt-re-mat.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-flt-re-mat.h	Wed Apr 28 13:46:02 2021 -0400
@@ -90,9 +90,9 @@
 
   octave_base_value * try_narrowing_conversion (void);
 
-  idx_vector index_vector (bool /* require_integers */ = false) const
+  octave::idx_vector index_vector (bool /* require_integers */ = false) const
   {
-    return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix));
+    return idx_cache ? *idx_cache : set_idx_cache (octave::idx_vector (matrix));
   }
 
   builtin_type_t builtin_type (void) const { return btyp_float; }
--- a/libinterp/octave-value/ov-intx.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-intx.h	Wed Apr 28 13:46:02 2021 -0400
@@ -301,9 +301,9 @@
     matrix_ref ().changesign ();
   }
 
-  idx_vector index_vector (bool /* require_integers */ = false) const
+  octave::idx_vector index_vector (bool /* require_integers */ = false) const
   {
-    return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix));
+    return idx_cache ? *idx_cache : set_idx_cache (octave::idx_vector (matrix));
   }
 
   int write (octave::stream& os, int block_size,
@@ -624,7 +624,8 @@
     scalar -= OCTAVE_INT_T (1);
   }
 
-  idx_vector index_vector (bool /* require_integers */ = false) const { return idx_vector (scalar); }
+  octave::idx_vector index_vector (bool /* require_integers */ = false) const
+  { return octave::idx_vector (scalar); }
 
   int write (octave::stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
--- a/libinterp/octave-value/ov-java.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-java.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -1121,7 +1121,7 @@
   for (int i = 0; i < idx.length (); i++)
     try
       {
-        idx_vector v = idx(i).index_vector ();
+        octave::idx_vector v = idx(i).index_vector ();
 
         jintArray_ref i_array (jni_env, jni_env->NewIntArray (v.length ()));
         jint *buf = jni_env->GetIntArrayElements (i_array, nullptr);
--- a/libinterp/octave-value/ov-lazy-idx.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-lazy-idx.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -81,8 +81,8 @@
 octave_value
 octave_lazy_index::reshape (const dim_vector& new_dims) const
 {
-  return idx_vector (index.as_array ().reshape (new_dims),
-                     index.extent (0));
+  return octave::idx_vector (index.as_array ().reshape (new_dims),
+                             index.extent (0));
 }
 
 octave_value
@@ -92,15 +92,14 @@
   if (value.is_defined ())
     return value.permute (vec, inv);
   else
-    return idx_vector (index.as_array ().permute (vec, inv),
-                       index.extent (0));
+    return octave::idx_vector (index.as_array ().permute (vec, inv),
+                               index.extent (0));
 }
 
 octave_value
 octave_lazy_index::squeeze (void) const
 {
-  return idx_vector (index.as_array ().squeeze (),
-                     index.extent (0));
+  return octave::idx_vector (index.as_array ().squeeze (), index.extent (0));
 }
 
 octave_value
@@ -112,8 +111,8 @@
       && (dim >= 0 && dim <= 1) && odims(1-dim) == 1)
     return index_vector ().sorted ();
   else
-    return idx_vector (index.as_array ().sort (dim, mode),
-                       index.extent (0));
+    return octave::idx_vector (index.as_array ().sort (dim, mode),
+                               index.extent (0));
 }
 
 octave_value
@@ -126,8 +125,8 @@
       && (dim >= 0 && dim <= 1) && odims(1-dim) == 1)
     return index_vector ().sorted (sidx);
   else
-    return idx_vector (index.as_array ().sort (sidx, dim, mode),
-                       index.extent (0));
+    return octave::idx_vector (index.as_array ().sort (sidx, dim, mode),
+                               index.extent (0));
 }
 
 sortmode
--- a/libinterp/octave-value/ov-lazy-idx.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-lazy-idx.h	Wed Apr 28 13:46:02 2021 -0400
@@ -42,7 +42,7 @@
   octave_lazy_index (void)
     : octave_base_value (), index (), value () { }
 
-  octave_lazy_index (const idx_vector& idx)
+  octave_lazy_index (const octave::idx_vector& idx)
     : octave_base_value (), index (idx), value () { }
 
   octave_lazy_index (const octave_lazy_index& i)
@@ -66,7 +66,8 @@
 
   octave_value full_value (void) const { return make_value (); }
 
-  idx_vector index_vector (bool /* require_integers */ = false) const { return index; }
+  octave::idx_vector index_vector (bool /* require_integers */ = false) const
+  { return index; }
 
   builtin_type_t builtin_type (void) const { return btyp_double; }
 
@@ -269,7 +270,7 @@
     return value;
   }
 
-  idx_vector index;
+  octave::idx_vector index;
   mutable octave_value value;
 
   static octave_base_value *
--- a/libinterp/octave-value/ov-magic-int.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-magic-int.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -85,7 +85,7 @@
 }
 
 template <typename T>
-idx_vector
+octave::idx_vector
 octave_base_magic_int<T>::index_vector (bool require_integers) const
 {
   octave_value tmp (double_value ());
--- a/libinterp/octave-value/ov-magic-int.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-magic-int.h	Wed Apr 28 13:46:02 2021 -0400
@@ -76,7 +76,7 @@
   octave_value do_index_op (const octave_value_list& idx,
                             bool resize_ok = false);
 
-  idx_vector index_vector (bool require_integers = false) const;
+  octave::idx_vector index_vector (bool require_integers = false) const;
 
   octave_value any (int = 0) const { return scalar_ref () != T (0); }
 
--- a/libinterp/octave-value/ov-perm.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-perm.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -74,7 +74,7 @@
 {
   octave_value retval;
   octave_idx_type nidx = idx.length ();
-  idx_vector idx0, idx1;
+  octave::idx_vector idx0, idx1;
   if (nidx == 2)
     {
       int k = 0;    // index we're processing when index_vector throws
@@ -240,7 +240,7 @@
 FORWARD_MATRIX_VALUE (boolNDArray, bool_array)
 FORWARD_MATRIX_VALUE (charNDArray, char_array)
 
-idx_vector
+octave::idx_vector
 octave_perm_matrix::index_vector (bool require_integers) const
 {
   return to_dense ().index_vector (require_integers);
--- a/libinterp/octave-value/ov-perm.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-perm.h	Wed Apr 28 13:46:02 2021 -0400
@@ -146,7 +146,7 @@
   double scalar_value (bool frc_str_conv = false) const
   { return double_value (frc_str_conv); }
 
-  idx_vector index_vector (bool require_integers = false) const;
+  octave::idx_vector index_vector (bool require_integers = false) const;
 
   PermMatrix perm_matrix_value (void) const
   { return matrix; }
--- a/libinterp/octave-value/ov-range.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-range.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -256,7 +256,7 @@
 
       try
         {
-          idx_vector i = idx(0).index_vector ();
+          octave::idx_vector i = idx(0).index_vector ();
 
           if (i.is_scalar () && i(0) < numel ())
             retval = m_range.elem (i(0));
@@ -282,7 +282,7 @@
 }
 
 template <typename T>
-idx_vector
+octave::idx_vector
 ov_range<T>::index_vector (bool require_integers) const
 {
   octave_value tmp (raw_array_value ());
@@ -1013,14 +1013,14 @@
 }
 
 template <>
-idx_vector
+octave::idx_vector
 ov_range<double>::index_vector (bool require_integers) const
 {
   if (m_idx_cache)
     return *m_idx_cache;
 
   if (require_integers || m_range.all_elements_are_ints ())
-    return set_idx_cache (idx_vector (m_range));
+    return set_idx_cache (octave::idx_vector (m_range));
 
   warning_with_id ("Octave:noninteger-range-as-index",
                    "non-integer range used as index");
--- a/libinterp/octave-value/ov-range.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-range.h	Wed Apr 28 13:46:02 2021 -0400
@@ -69,10 +69,11 @@
 
   ov_range (const ov_range<T>& r)
     : octave_base_value (), m_range (r.m_range),
-      m_idx_cache (r.m_idx_cache ? new idx_vector (*r.m_idx_cache) : nullptr)
+      m_idx_cache (r.m_idx_cache
+                   ? new octave::idx_vector (*r.m_idx_cache) : nullptr)
   { }
 
-  ov_range (const octave::range<T>& r, const idx_vector& cache)
+  ov_range (const octave::range<T>& r, const octave::idx_vector& cache)
     : octave_base_value (), m_range (r), m_idx_cache ()
   {
     set_idx_cache (cache);
@@ -118,7 +119,7 @@
   OCTINTERP_API octave_value
   do_index_op (const octave_value_list& idx, bool resize_ok = false);
 
-  OCTINTERP_API idx_vector index_vector (bool require_integers = false) const;
+  OCTINTERP_API octave::idx_vector index_vector (bool require_integers = false) const;
 
   dim_vector dims (void) const
   {
@@ -473,10 +474,10 @@
 
   octave::range<T> m_range;
 
-  idx_vector set_idx_cache (const idx_vector& idx) const
+  octave::idx_vector set_idx_cache (const octave::idx_vector& idx) const
   {
     delete m_idx_cache;
-    m_idx_cache = (idx ? new idx_vector (idx) : nullptr);
+    m_idx_cache = (idx ? new octave::idx_vector (idx) : nullptr);
     return idx;
   }
 
@@ -485,7 +486,7 @@
     delete m_idx_cache; m_idx_cache = nullptr;
   }
 
-  mutable idx_vector *m_idx_cache;
+  mutable octave::idx_vector *m_idx_cache;
 
   static octave_hdf5_id hdf5_save_type;
 
@@ -549,7 +550,7 @@
 // performance until solutions can be generalized for other types.
 
 template <>
-OCTINTERP_API idx_vector
+OCTINTERP_API octave::idx_vector
 ov_range<double>::index_vector (bool require_integers) const;
 
 template <>
--- a/libinterp/octave-value/ov-re-diag.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-re-diag.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -98,9 +98,9 @@
       int k = 0;        // index we're accessing when index_vector throws
       try
         {
-          idx_vector idx0 = idx(0).index_vector ();
+          octave::idx_vector idx0 = idx(0).index_vector ();
           k = 1;
-          idx_vector idx1 = idx(1).index_vector ();
+          octave::idx_vector idx1 = idx(1).index_vector ();
 
           bool left = idx0.is_permutation (matrix.rows ());
           bool right = idx1.is_permutation (matrix.cols ());
--- a/libinterp/octave-value/ov-re-mat.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-re-mat.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -341,8 +341,8 @@
   if (idx_cache)
     {
       return new octave_matrix (matrix.reshape (new_dims),
-                                idx_vector (idx_cache->as_array ().reshape (new_dims),
-                                            idx_cache->extent (0)));
+                                octave::idx_vector (idx_cache->as_array ().reshape (new_dims),
+                                                    idx_cache->extent (0)));
     }
   else
     return octave_base_matrix<NDArray>::reshape (new_dims);
@@ -354,8 +354,8 @@
   if (idx_cache)
     {
       return new octave_matrix (matrix.squeeze (),
-                                idx_vector (idx_cache->as_array ().squeeze (),
-                                            idx_cache->extent (0)));
+                                octave::idx_vector (idx_cache->as_array ().squeeze (),
+                                                    idx_cache->extent (0)));
     }
   else
     return octave_base_matrix<NDArray>::squeeze ();
--- a/libinterp/octave-value/ov-re-mat.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-re-mat.h	Wed Apr 28 13:46:02 2021 -0400
@@ -87,10 +87,10 @@
   {
     // Auto-create cache to speed up subsequent indexing.
     if (zero_based && cache_index)
-      set_idx_cache (idx_vector (idx));
+      set_idx_cache (octave::idx_vector (idx));
   }
 
-  octave_matrix (const NDArray& nda, const idx_vector& cache)
+  octave_matrix (const NDArray& nda, const octave::idx_vector& cache)
     : octave_base_matrix<NDArray> (nda)
   {
     set_idx_cache (cache);
@@ -105,8 +105,8 @@
 
   octave_base_value * try_narrowing_conversion (void);
 
-  idx_vector index_vector (bool /* require_integers */ = false) const
-  { return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix)); }
+  octave::idx_vector index_vector (bool /* require_integers */ = false) const
+  { return idx_cache ? *idx_cache : set_idx_cache (octave::idx_vector (matrix)); }
 
   builtin_type_t builtin_type (void) const { return btyp_double; }
 
--- a/libinterp/octave-value/ov-re-sparse.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-re-sparse.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -57,11 +57,11 @@
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_matrix, "sparse matrix",
                                      "double");
 
-idx_vector
+octave::idx_vector
 octave_sparse_matrix::index_vector (bool /* require_integers */) const
 {
   if (matrix.numel () == matrix.nnz ())
-    return idx_vector (array_value ());
+    return octave::idx_vector (array_value ());
   else
     {
       std::string nm = '<' + type_name () + '>';
--- a/libinterp/octave-value/ov-re-sparse.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-re-sparse.h	Wed Apr 28 13:46:02 2021 -0400
@@ -93,7 +93,7 @@
 
   octave_base_value * try_narrowing_conversion (void);
 
-  idx_vector index_vector (bool require_integers = false) const;
+  octave::idx_vector index_vector (bool require_integers = false) const;
 
   builtin_type_t builtin_type (void) const { return btyp_double; }
 
--- a/libinterp/octave-value/ov-scalar.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-scalar.h	Wed Apr 28 13:46:02 2021 -0400
@@ -78,7 +78,8 @@
 
   type_conv_info numeric_demotion_function (void) const;
 
-  idx_vector index_vector (bool /* require_integers */ = false) const { return idx_vector (scalar); }
+  octave::idx_vector index_vector (bool /* require_integers */ = false) const
+  { return octave::idx_vector (scalar); }
 
   octave_value any (int = 0) const
   { return (scalar != 0 && ! lo_ieee_isnan (scalar)); }
--- a/libinterp/octave-value/ov-str-mat.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-str-mat.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -110,7 +110,7 @@
 
         case 1:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
 
             retval = octave_value (charNDArray (matrix.index (i, resize_ok)),
                                    type);
@@ -119,9 +119,9 @@
 
         case 2:
           {
-            idx_vector i = idx (0).index_vector ();
+            octave::idx_vector i = idx (0).index_vector ();
             k = 1;
-            idx_vector j = idx (1).index_vector ();
+            octave::idx_vector j = idx (1).index_vector ();
 
             retval = octave_value (charNDArray (matrix.index (i, j, resize_ok)),
                                    type);
@@ -130,7 +130,7 @@
 
         default:
           {
-            Array<idx_vector> idx_vec (dim_vector (len, 1));
+            Array<octave::idx_vector> idx_vec (dim_vector (len, 1));
 
             for (k = 0; k < len; k++)
               idx_vec(k) = idx(k).index_vector ();
--- a/libinterp/octave-value/ov-struct.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov-struct.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -2121,7 +2121,7 @@
     }
 
   octave_map map (rdv);
-  Array<idx_vector> ia (dim_vector (nd, 1), idx_vector::colon);
+  Array<octave::idx_vector> ia (dim_vector (nd, 1), octave::idx_vector::colon);
 
   for (octave_idx_type i = 0; i < ext; i++)
     {
--- a/libinterp/octave-value/ov.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -1004,22 +1004,22 @@
   maybe_mutate ();
 }
 
-octave_value::octave_value (const idx_vector& idx, bool lazy)
+octave_value::octave_value (const octave::idx_vector& idx, bool lazy)
   : rep ()
 {
   double scalar;
   octave::range<double> range;
   NDArray array;
   boolNDArray mask;
-  idx_vector::idx_class_type idx_class;
+  octave::idx_vector::idx_class_type idx_class;
 
   if (lazy)
     {
       // Only make lazy indices out of ranges and index vectors.
       switch (idx.idx_class ())
         {
-        case idx_vector::class_range:
-        case idx_vector::class_vector:
+        case octave::idx_vector::class_range:
+        case octave::idx_vector::class_vector:
           rep = new octave_lazy_index (idx);
           maybe_mutate ();
           return;
@@ -1033,23 +1033,23 @@
 
   switch (idx_class)
     {
-    case idx_vector::class_colon:
+    case octave::idx_vector::class_colon:
       rep = new octave_magic_colon ();
       break;
 
-    case idx_vector::class_range:
+    case octave::idx_vector::class_range:
       rep = new octave_range (range, idx);
       break;
 
-    case idx_vector::class_scalar:
+    case octave::idx_vector::class_scalar:
       rep = new octave_scalar (scalar);
       break;
 
-    case idx_vector::class_vector:
+    case octave::idx_vector::class_vector:
       rep = new octave_matrix (array, idx);
       break;
 
-    case idx_vector::class_mask:
+    case octave::idx_vector::class_mask:
       rep = new octave_bool_matrix (mask, idx);
       break;
 
--- a/libinterp/octave-value/ov.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/octave-value/ov.h	Wed Apr 28 13:46:02 2021 -0400
@@ -285,7 +285,7 @@
                               bool zero_based = false,
                               bool cache_index = false);
   OCTINTERP_API octave_value (const Array<std::string>& cellstr);
-  OCTINTERP_API octave_value (const idx_vector& idx, bool lazy = true);
+  OCTINTERP_API octave_value (const octave::idx_vector& idx, bool lazy = true);
   OCTAVE_DEPRECATED (7, "use 'octave_value (range<double>&)' instead")
   OCTINTERP_API octave_value (double base, double limit, double inc);
   OCTAVE_DEPRECATED (7, "use 'octave_value (range<double>&)' instead")
@@ -532,7 +532,7 @@
 
   OCTINTERP_API octave_value& assign (assign_op, const octave_value& rhs);
 
-  idx_vector index_vector (bool require_integers = false) const
+  octave::idx_vector index_vector (bool require_integers = false) const
   {
     return rep->index_vector (require_integers);
   }
--- a/libinterp/template-inst/Array-jit.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/template-inst/Array-jit.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -37,7 +37,7 @@
 // Prevent implicit instantiations on some systems (Windows, others?)
 // that can lead to duplicate definitions of static data members.
 
-extern template class Array<idx_vector>;
+extern template class Array<octave::idx_vector>;
 extern template class Array<octave_idx_type>;
 
 NO_INSTANTIATE_ARRAY_SORT (octave::jit_function, OCTINTERP_API);
--- a/libinterp/template-inst/Array-tc.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/libinterp/template-inst/Array-tc.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -47,7 +47,7 @@
 extern template class Array<char>;
 extern template class Array<double>;
 extern template class Array<float>;
-extern template class Array<idx_vector>;
+extern template class Array<octave::idx_vector>;
 extern template class Array<octave_idx_type>;
 extern template class Array<std::string>;
 
--- a/liboctave/array/Array-C.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-C.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -39,7 +39,7 @@
 // Prevent implicit instantiations on some systems (Windows, others?)
 // that can lead to duplicate definitions of static data members.
 
-extern template class Array<idx_vector>;
+extern template class Array<octave::idx_vector>;
 extern template class Array<octave_idx_type>;
 
 template <>
--- a/liboctave/array/Array-b.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-b.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -39,7 +39,7 @@
 // Prevent implicit instantiations on some systems (Windows, others?)
 // that can lead to duplicate definitions of static data members.
 
-extern template class Array<idx_vector>;
+extern template class Array<octave::idx_vector>;
 extern template class Array<octave_idx_type>;
 
 // Specialize bool sorting (aka stable partitioning).
--- a/liboctave/array/Array-ch.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-ch.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -39,7 +39,7 @@
 // Prevent implicit instantiations on some systems (Windows, others?)
 // that can lead to duplicate definitions of static data members.
 
-extern template class Array<idx_vector>;
+extern template class Array<octave::idx_vector>;
 extern template class Array<octave_idx_type>;
 
 template class octave_sort<char>;
--- a/liboctave/array/Array-d.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-d.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -41,7 +41,7 @@
 // Prevent implicit instantiations on some systems (Windows, others?)
 // that can lead to duplicate definitions of static data members.
 
-extern template class Array<idx_vector>;
+extern template class Array<octave::idx_vector>;
 extern template class Array<octave_idx_type>;
 
 template <>
--- a/liboctave/array/Array-f.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-f.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -41,7 +41,7 @@
 // Prevent implicit instantiations on some systems (Windows, others?)
 // that can lead to duplicate definitions of static data members.
 
-extern template class Array<idx_vector>;
+extern template class Array<octave::idx_vector>;
 extern template class Array<octave_idx_type>;
 
 template <>
--- a/liboctave/array/Array-fC.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-fC.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -39,7 +39,7 @@
 // Prevent implicit instantiations on some systems (Windows, others?)
 // that can lead to duplicate definitions of static data members.
 
-extern template class Array<idx_vector>;
+extern template class Array<octave::idx_vector>;
 extern template class Array<octave_idx_type>;
 
 template <>
--- a/liboctave/array/Array-i.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-i.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -41,7 +41,7 @@
 // Prevent implicit instantiations on some systems (Windows, others?)
 // that can lead to duplicate definitions of static data members.
 
-extern template class Array<idx_vector>;
+extern template class Array<octave::idx_vector>;
 
 template class octave_sort<signed char>;
 //template class octave_sort<short>;
--- a/liboctave/array/Array-idx-vec.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-idx-vec.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -39,6 +39,6 @@
 
 extern template class Array<octave_idx_type>;
 
-NO_INSTANTIATE_ARRAY_SORT (idx_vector, OCTAVE_API);
+NO_INSTANTIATE_ARRAY_SORT (octave::idx_vector, OCTAVE_API);
 
-INSTANTIATE_ARRAY (idx_vector, OCTAVE_API);
+INSTANTIATE_ARRAY (octave::idx_vector, OCTAVE_API);
--- a/liboctave/array/Array-s.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-s.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -39,7 +39,7 @@
 // Prevent implicit instantiations on some systems (Windows, others?)
 // that can lead to duplicate definitions of static data members.
 
-extern template class Array<idx_vector>;
+extern template class Array<octave::idx_vector>;
 extern template class Array<octave_idx_type>;
 
 template class octave_sort<short>;
--- a/liboctave/array/Array-str.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-str.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -39,7 +39,7 @@
 // Prevent implicit instantiations on some systems (Windows, others?)
 // that can lead to duplicate definitions of static data members.
 
-extern template class Array<idx_vector>;
+extern template class Array<octave::idx_vector>;
 extern template class Array<octave_idx_type>;
 
 template class octave_sort<std::string>;
--- a/liboctave/array/Array-util.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-util.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -236,7 +236,7 @@
 }
 
 Array<octave_idx_type>
-conv_to_int_array (const Array<idx_vector>& a)
+conv_to_int_array (const Array<octave::idx_vector>& a)
 {
   Array<octave_idx_type> retval (a.dims ());
 
@@ -246,10 +246,10 @@
   return retval;
 }
 
-Array<idx_vector>
-conv_to_array (const idx_vector *tmp, const octave_idx_type len)
+Array<octave::idx_vector>
+conv_to_array (const octave::idx_vector *tmp, const octave_idx_type len)
 {
-  Array<idx_vector> retval (dim_vector (len, 1));
+  Array<octave::idx_vector> retval (dim_vector (len, 1));
 
   for (octave_idx_type i = 0; i < len; i++)
     retval(i) = tmp[i];
@@ -258,7 +258,7 @@
 }
 
 dim_vector
-freeze (Array<idx_vector>& ra_idx, const dim_vector& dimensions, int resize_ok)
+freeze (Array<octave::idx_vector>& ra_idx, const dim_vector& dimensions, int resize_ok)
 {
   dim_vector retval;
 
@@ -299,7 +299,7 @@
 }
 
 bool
-all_ok (const Array<idx_vector>& ra_idx)
+all_ok (const Array<octave::idx_vector>& ra_idx)
 {
   bool retval = true;
 
@@ -318,7 +318,7 @@
 }
 
 bool
-any_orig_empty (const Array<idx_vector>& ra_idx)
+any_orig_empty (const Array<octave::idx_vector>& ra_idx)
 {
   bool retval = false;
 
@@ -337,7 +337,7 @@
 }
 
 bool
-all_colon_equiv (const Array<idx_vector>& ra_idx,
+all_colon_equiv (const Array<octave::idx_vector>& ra_idx,
                  const dim_vector& frozen_lengths)
 {
   bool retval = true;
@@ -378,7 +378,7 @@
 }
 
 Array<octave_idx_type>
-get_elt_idx (const Array<idx_vector>& ra_idx,
+get_elt_idx (const Array<octave::idx_vector>& ra_idx,
              const Array<octave_idx_type>& result_idx)
 {
   octave_idx_type n = ra_idx.numel ();
@@ -426,7 +426,7 @@
 }
 
 dim_vector
-zero_dims_inquire (const Array<idx_vector>& ia, const dim_vector& rhdv)
+zero_dims_inquire (const Array<octave::idx_vector>& ia, const dim_vector& rhdv)
 {
   int ial = ia.numel ();
   int rhdvl = rhdv.ndims ();
@@ -483,7 +483,7 @@
 }
 
 dim_vector
-zero_dims_inquire (const idx_vector& i, const idx_vector& j,
+zero_dims_inquire (const octave::idx_vector& i, const octave::idx_vector& j,
                    const dim_vector& rhdv)
 {
   bool icol = i.is_colon ();
@@ -531,10 +531,10 @@
   void operator ()(octave_idx_type k) { (*ind++ *= n) += k; }
 };
 
-idx_vector
-sub2ind (const dim_vector& dv, const Array<idx_vector>& idxa)
+octave::idx_vector
+sub2ind (const dim_vector& dv, const Array<octave::idx_vector>& idxa)
 {
-  idx_vector retval;
+  octave::idx_vector retval;
   octave_idx_type len = idxa.numel ();
 
   if (len == 0)
@@ -548,7 +548,7 @@
     {
       try
         {
-          idx_vector idx = idxa(i);
+          octave::idx_vector idx = idxa(i);
           octave_idx_type n = dvx(i);
 
           all_ranges = all_ranges && idx.is_range ();
@@ -581,7 +581,7 @@
       octave_idx_type idx = idxa(len-1)(0);
       for (octave_idx_type i = len - 2; i >= 0; i--)
         idx = dvx(i) * idx + idxa(i)(0);
-      retval = idx_vector (idx);
+      retval = octave::idx_vector (idx);
     }
   else if (all_ranges && clen != 0)
     {
@@ -595,7 +595,7 @@
           start = dvx(i) * start + xstart;
           step = dvx(i) * step + xstep;
         }
-      retval = idx_vector::make_range (start, step, clen);
+      retval = octave::idx_vector::make_range (start, step, clen);
     }
   else
     {
@@ -610,18 +610,18 @@
             idxa(i).copy_data (idx_vec);
         }
 
-      retval = idx_vector (idx);
+      retval = octave::idx_vector (idx);
     }
 
   return retval;
 }
 
-Array<idx_vector>
-ind2sub (const dim_vector& dv, const idx_vector& idx)
+Array<octave::idx_vector>
+ind2sub (const dim_vector& dv, const octave::idx_vector& idx)
 {
   octave_idx_type len = idx.length (0);
   octave_idx_type n = dv.ndims ();
-  Array<idx_vector> retval (dim_vector (n, 1));
+  Array<octave::idx_vector> retval (dim_vector (n, 1));
   octave_idx_type numel = dv.numel ();
 
   if (idx.extent (numel) > numel)
--- a/liboctave/array/Array-util.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-util.h	Wed Apr 28 13:46:02 2021 -0400
@@ -66,45 +66,47 @@
 compute_index (const Array<octave_idx_type>& ra_idx, const dim_vector& dims);
 
 extern OCTAVE_API Array<octave_idx_type>
-conv_to_int_array (const Array<idx_vector>& a);
+conv_to_int_array (const Array<octave::idx_vector>& a);
 
-extern OCTAVE_API Array<idx_vector> conv_to_array (const idx_vector *tmp,
-                                                   const octave_idx_type len);
+extern OCTAVE_API Array<octave::idx_vector>
+conv_to_array (const octave::idx_vector *tmp, const octave_idx_type len);
 
-extern OCTAVE_API dim_vector freeze (Array<idx_vector>& ra_idx,
-                                     const dim_vector& dimensions,
-                                     int resize_ok);
+extern OCTAVE_API dim_vector
+freeze (Array<octave::idx_vector>& ra_idx, const dim_vector& dimensions,
+        int resize_ok);
 
 extern OCTAVE_API bool vector_equivalent (const dim_vector& dv);
 
-extern OCTAVE_API bool all_ok (const Array<idx_vector>& ra_idx);
+extern OCTAVE_API bool all_ok (const Array<octave::idx_vector>& ra_idx);
 
-extern OCTAVE_API bool any_orig_empty (const Array<idx_vector>& ra_idx);
+extern OCTAVE_API bool
+any_orig_empty (const Array<octave::idx_vector>& ra_idx);
 
-extern OCTAVE_API bool all_colon_equiv (const Array<idx_vector>& ra_idx,
-                                        const dim_vector& frozen_lengths);
+extern OCTAVE_API bool
+all_colon_equiv (const Array<octave::idx_vector>& ra_idx,
+                 const dim_vector& frozen_lengths);
 
 extern OCTAVE_API bool all_ones (const Array<octave_idx_type>& arr);
 
 extern OCTAVE_API Array<octave_idx_type>
-get_elt_idx (const Array<idx_vector>& ra_idx,
+get_elt_idx (const Array<octave::idx_vector>& ra_idx,
              const Array<octave_idx_type>& result_idx);
 
 extern OCTAVE_API Array<octave_idx_type> get_ra_idx (octave_idx_type idx,
                                                      const dim_vector& dims);
 
-extern OCTAVE_API dim_vector zero_dims_inquire (const Array<idx_vector>& ia,
-                                                const dim_vector& rhdv);
+extern OCTAVE_API dim_vector
+zero_dims_inquire (const Array<octave::idx_vector>& ia, const dim_vector& rhdv);
 
-extern OCTAVE_API dim_vector zero_dims_inquire (const idx_vector& i,
-                                                const idx_vector& j,
-                                                const dim_vector& rhdv);
+extern OCTAVE_API dim_vector
+zero_dims_inquire (const octave::idx_vector& i, const octave::idx_vector& j,
+                   const dim_vector& rhdv);
 
-extern OCTAVE_API idx_vector sub2ind (const dim_vector& dv,
-                                      const Array<idx_vector>& idxa);
+extern OCTAVE_API octave::idx_vector
+sub2ind (const dim_vector& dv, const Array<octave::idx_vector>& idxa);
 
-extern OCTAVE_API Array<idx_vector> ind2sub (const dim_vector& dv,
-                                             const idx_vector& idx);
+extern OCTAVE_API Array<octave::idx_vector>
+ind2sub (const dim_vector& dv, const octave::idx_vector& idx);
 
 struct
 permute_vector
--- a/liboctave/array/Array-voidp.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array-voidp.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -37,7 +37,7 @@
 // Prevent implicit instantiations on some systems (Windows, others?)
 // that can lead to duplicate definitions of static data members.
 
-extern template class Array<idx_vector>;
+extern template class Array<octave::idx_vector>;
 extern template class Array<octave_idx_type>;
 
 NO_INSTANTIATE_ARRAY_SORT (void *, OCTAVE_API);
--- a/liboctave/array/Array.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -510,12 +510,12 @@
   int top;
   octave_idx_type *dim;
   octave_idx_type *cdim;
-  idx_vector *idx;
+  octave::idx_vector *idx;
 
 public:
-  rec_index_helper (const dim_vector& dv, const Array<idx_vector>& ia)
+  rec_index_helper (const dim_vector& dv, const Array<octave::idx_vector>& ia)
     : n (ia.numel ()), top (0), dim (new octave_idx_type [2*n]),
-      cdim (dim + n), idx (new idx_vector [n])
+      cdim (dim + n), idx (new octave::idx_vector [n])
   {
     assert (n > 0 && (dv.ndims () == std::max (n, 2)));
 
@@ -695,7 +695,7 @@
 
 template <typename T>
 Array<T>
-Array<T>::index (const idx_vector& i) const
+Array<T>::index (const octave::idx_vector& i) const
 {
   // Colon:
   //
@@ -762,7 +762,7 @@
 
 template <typename T>
 Array<T>
-Array<T>::index (const idx_vector& i, const idx_vector& j) const
+Array<T>::index (const octave::idx_vector& i, const octave::idx_vector& j) const
 {
   // Get dimensions, allowing Fortran indexing in the 2nd dim.
   dim_vector dv = dimensions.redim (2);
@@ -786,7 +786,7 @@
       octave_idx_type il = i.length (r);
       octave_idx_type jl = j.length (c);
 
-      idx_vector ii (i);
+      octave::idx_vector ii (i);
 
       if (ii.maybe_reduce (r, j, c))
         {
@@ -820,7 +820,7 @@
 
 template <typename T>
 Array<T>
-Array<T>::index (const Array<idx_vector>& ia) const
+Array<T>::index (const Array<octave::idx_vector>& ia) const
 {
   int ial = ia.numel ();
   Array<T> retval;
@@ -1030,7 +1030,7 @@
 
 template <typename T>
 Array<T>
-Array<T>::index (const idx_vector& i, bool resize_ok, const T& rfv) const
+Array<T>::index (const octave::idx_vector& i, bool resize_ok, const T& rfv) const
 {
   Array<T> tmp = *this;
   if (resize_ok)
@@ -1054,7 +1054,7 @@
 
 template <typename T>
 Array<T>
-Array<T>::index (const idx_vector& i, const idx_vector& j,
+Array<T>::index (const octave::idx_vector& i, const octave::idx_vector& j,
                  bool resize_ok, const T& rfv) const
 {
   Array<T> tmp = *this;
@@ -1082,7 +1082,7 @@
 
 template <typename T>
 Array<T>
-Array<T>::index (const Array<idx_vector>& ia,
+Array<T>::index (const Array<octave::idx_vector>& ia,
                  bool resize_ok, const T& rfv) const
 {
   Array<T> tmp = *this;
@@ -1113,7 +1113,7 @@
 
 template <typename T>
 void
-Array<T>::assign (const idx_vector& i, const Array<T>& rhs, const T& rfv)
+Array<T>::assign (const octave::idx_vector& i, const Array<T>& rhs, const T& rfv)
 {
   octave_idx_type n = numel ();
   octave_idx_type rhl = rhs.numel ();
@@ -1160,7 +1160,7 @@
 // Assignment to a 2-dimensional array
 template <typename T>
 void
-Array<T>::assign (const idx_vector& i, const idx_vector& j,
+Array<T>::assign (const octave::idx_vector& i, const octave::idx_vector& j,
                   const Array<T>& rhs, const T& rfv)
 {
   bool initial_dims_all_zero = dimensions.all_zero ();
@@ -1228,7 +1228,7 @@
           octave_idx_type n = numel ();
           octave_idx_type r = dv(0);
           octave_idx_type c = dv(1);
-          idx_vector ii (i);
+          octave::idx_vector ii (i);
 
           const T *src = rhs.data ();
           T *dest = fortran_vec ();
@@ -1264,7 +1264,7 @@
 // Assignment to a multi-dimensional array
 template <typename T>
 void
-Array<T>::assign (const Array<idx_vector>& ia,
+Array<T>::assign (const Array<octave::idx_vector>& ia,
                   const Array<T>& rhs, const T& rfv)
 {
   int ial = ia.numel ();
@@ -1392,7 +1392,7 @@
 
 template <typename T>
 void
-Array<T>::delete_elements (const idx_vector& i)
+Array<T>::delete_elements (const octave::idx_vector& i)
 {
   octave_idx_type n = numel ();
   if (i.is_colon ())
@@ -1432,7 +1432,7 @@
 
 template <typename T>
 void
-Array<T>::delete_elements (int dim, const idx_vector& i)
+Array<T>::delete_elements (int dim, const octave::idx_vector& i)
 {
   if (dim < 0 || dim >= ndims ())
     (*current_liboctave_error_handler) ("invalid dimension in delete_elements");
@@ -1479,7 +1479,7 @@
       else
         {
           // Use index.
-          Array<idx_vector> ia (dim_vector (ndims (), 1), idx_vector::colon);
+          Array<octave::idx_vector> ia (dim_vector (ndims (), 1), octave::idx_vector::colon);
           ia (dim) = i.complement (n);
           *this = index (ia);
         }
@@ -1488,7 +1488,7 @@
 
 template <typename T>
 void
-Array<T>::delete_elements (const Array<idx_vector>& ia)
+Array<T>::delete_elements (const Array<octave::idx_vector>& ia)
 {
   int ial = ia.numel ();
 
@@ -1567,17 +1567,17 @@
 Array<T>&
 Array<T>::insert (const Array<T>& a, octave_idx_type r, octave_idx_type c)
 {
-  idx_vector i (r, r + a.rows ());
-  idx_vector j (c, c + a.columns ());
+  octave::idx_vector i (r, r + a.rows ());
+  octave::idx_vector j (c, c + a.columns ());
   if (ndims () == 2 && a.ndims () == 2)
     assign (i, j, a);
   else
     {
-      Array<idx_vector> idx (dim_vector (a.ndims (), 1));
+      Array<octave::idx_vector> idx (dim_vector (a.ndims (), 1));
       idx(0) = i;
       idx(1) = j;
       for (int k = 2; k < a.ndims (); k++)
-        idx(k) = idx_vector (0, a.dimensions(k));
+        idx(k) = octave::idx_vector (0, a.dimensions(k));
       assign (idx, a);
     }
 
@@ -1589,10 +1589,10 @@
 Array<T>::insert (const Array<T>& a, const Array<octave_idx_type>& ra_idx)
 {
   octave_idx_type n = ra_idx.numel ();
-  Array<idx_vector> idx (dim_vector (n, 1));
+  Array<octave::idx_vector> idx (dim_vector (n, 1));
   const dim_vector dva = a.dims ().redim (n);
   for (octave_idx_type k = 0; k < n; k++)
-    idx(k) = idx_vector (ra_idx(k), ra_idx(k) + dva(k));
+    idx(k) = octave::idx_vector (ra_idx(k), ra_idx(k) + dva(k));
 
   assign (idx, a);
 
@@ -2308,7 +2308,7 @@
 
 template <typename T>
 Array<T>
-Array<T>::nth_element (const idx_vector& n, int dim) const
+Array<T>::nth_element (const octave::idx_vector& n, int dim) const
 {
   if (dim < 0)
     (*current_liboctave_error_handler) ("nth_element: invalid dimension");
@@ -2335,11 +2335,11 @@
 
   switch (n.idx_class ())
     {
-    case idx_vector::class_scalar:
+    case octave::idx_vector::class_scalar:
       mode = ASCENDING;
       lo = n(0);
       break;
-    case idx_vector::class_range:
+    case octave::idx_vector::class_range:
       {
         octave_idx_type inc = n.increment ();
         if (inc == 1)
@@ -2354,7 +2354,7 @@
           }
       }
       break;
-    case idx_vector::class_vector:
+    case octave::idx_vector::class_vector:
       // This case resolves bug #51329, a fallback to allow the given index
       // to be a sequential vector instead of the typical scalar or range
       if (n(1) - n(0) == 1)
@@ -2524,7 +2524,7 @@
     return Array<octave_idx_type> ();                                   \
   }                                                                     \
   template <> API Array<T>                                              \
-  Array<T>::nth_element (const idx_vector&, int) const {                \
+  Array<T>::nth_element (const octave::idx_vector&, int) const {                \
     return Array<T> ();                                                 \
   }
 
@@ -2702,7 +2702,7 @@
     return retval;
 
   int nidx = std::max (dv.ndims (), static_cast<octave_idx_type> (dim + 1));
-  Array<idx_vector> idxa (dim_vector (nidx, 1), idx_vector::colon);
+  Array<octave::idx_vector> idxa (dim_vector (nidx, 1), octave::idx_vector::colon);
   octave_idx_type l = 0;
 
   for (octave_idx_type i = 0; i < n; i++)
@@ -2724,7 +2724,7 @@
       else
         u = l + 1;
 
-      idxa(dim) = idx_vector (l, u);
+      idxa(dim) = octave::idx_vector (l, u);
 
       retval.assign (idxa, array_list[i]);
 
--- a/liboctave/array/Array.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Array.h	Wed Apr 28 13:46:02 2021 -0400
@@ -593,11 +593,11 @@
 
   //@{
   //! Indexing without resizing.
-  OCTARRAY_API Array<T> index (const idx_vector& i) const;
+  OCTARRAY_API Array<T> index (const octave::idx_vector& i) const;
 
-  OCTARRAY_API Array<T> index (const idx_vector& i, const idx_vector& j) const;
+  OCTARRAY_API Array<T> index (const octave::idx_vector& i, const octave::idx_vector& j) const;
 
-  OCTARRAY_API Array<T> index (const Array<idx_vector>& ia) const;
+  OCTARRAY_API Array<T> index (const Array<octave::idx_vector>& ia) const;
   //@}
 
   virtual OCTARRAY_API T resize_fill_value (void) const;
@@ -623,23 +623,23 @@
   // FIXME: this is really a corner case, that should better be
   // handled directly in liboctinterp.
 
-  OCTARRAY_API Array<T> index (const idx_vector& i, bool resize_ok, const T& rfv) const;
-  Array<T> index (const idx_vector& i, bool resize_ok) const
+  OCTARRAY_API Array<T> index (const octave::idx_vector& i, bool resize_ok, const T& rfv) const;
+  Array<T> index (const octave::idx_vector& i, bool resize_ok) const
   {
     return index (i, resize_ok, resize_fill_value ());
   }
 
-  OCTARRAY_API Array<T> index (const idx_vector& i, const idx_vector& j, bool resize_ok,
+  OCTARRAY_API Array<T> index (const octave::idx_vector& i, const octave::idx_vector& j, bool resize_ok,
                   const T& rfv) const;
-  Array<T> index (const idx_vector& i, const idx_vector& j,
+  Array<T> index (const octave::idx_vector& i, const octave::idx_vector& j,
                   bool resize_ok) const
   {
     return index (i, j, resize_ok, resize_fill_value ());
   }
 
-  OCTARRAY_API Array<T> index (const Array<idx_vector>& ia, bool resize_ok,
+  OCTARRAY_API Array<T> index (const Array<octave::idx_vector>& ia, bool resize_ok,
                   const T& rfv) const;
-  Array<T> index (const Array<idx_vector>& ia, bool resize_ok) const
+  Array<T> index (const Array<octave::idx_vector>& ia, bool resize_ok) const
   {
     return index (ia, resize_ok, resize_fill_value ());
   }
@@ -647,21 +647,21 @@
 
   //@{
   //! Indexed assignment (always with resize & fill).
-  OCTARRAY_API void assign (const idx_vector& i, const Array<T>& rhs, const T& rfv);
-  void assign (const idx_vector& i, const Array<T>& rhs)
+  OCTARRAY_API void assign (const octave::idx_vector& i, const Array<T>& rhs, const T& rfv);
+  void assign (const octave::idx_vector& i, const Array<T>& rhs)
   {
     assign (i, rhs, resize_fill_value ());
   }
 
-  OCTARRAY_API void assign (const idx_vector& i, const idx_vector& j, const Array<T>& rhs,
+  OCTARRAY_API void assign (const octave::idx_vector& i, const octave::idx_vector& j, const Array<T>& rhs,
                const T& rfv);
-  void assign (const idx_vector& i, const idx_vector& j, const Array<T>& rhs)
+  void assign (const octave::idx_vector& i, const octave::idx_vector& j, const Array<T>& rhs)
   {
     assign (i, j, rhs, resize_fill_value ());
   }
 
-  OCTARRAY_API void assign (const Array<idx_vector>& ia, const Array<T>& rhs, const T& rfv);
-  void assign (const Array<idx_vector>& ia, const Array<T>& rhs)
+  OCTARRAY_API void assign (const Array<octave::idx_vector>& ia, const Array<T>& rhs, const T& rfv);
+  void assign (const Array<octave::idx_vector>& ia, const Array<T>& rhs)
   {
     assign (ia, rhs, resize_fill_value ());
   }
@@ -671,13 +671,13 @@
   //! Deleting elements.
 
   //! A(I) = [] (with a single subscript)
-  OCTARRAY_API void delete_elements (const idx_vector& i);
+  OCTARRAY_API void delete_elements (const octave::idx_vector& i);
 
   //! A(:,...,I,...,:) = [] (>= 2 subscripts, one of them is non-colon)
-  OCTARRAY_API void delete_elements (int dim, const idx_vector& i);
+  OCTARRAY_API void delete_elements (int dim, const octave::idx_vector& i);
 
   //! Dispatcher to the above two.
-  OCTARRAY_API void delete_elements (const Array<idx_vector>& ia);
+  OCTARRAY_API void delete_elements (const Array<octave::idx_vector>& ia);
   //@}
 
   //! Insert an array into another at a specified position.  If
@@ -740,7 +740,7 @@
   //! Returns the n-th element in increasing order, using the same
   //! ordering as used for sort.  n can either be a scalar index or a
   //! contiguous range.
-  OCTARRAY_API Array<T> nth_element (const idx_vector& n, int dim = 0) const;
+  OCTARRAY_API Array<T> nth_element (const octave::idx_vector& n, int dim = 0) const;
 
   //! Get the kth super or subdiagonal.  The zeroth diagonal is the
   //! ordinary diagonal.
--- a/liboctave/array/CMatrix.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/CMatrix.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -686,14 +686,14 @@
   if (r1 > r2) { std::swap (r1, r2); }
   if (c1 > c2) { std::swap (c1, c2); }
 
-  return index (idx_vector (r1, r2+1), idx_vector (c1, c2+1));
+  return index (octave::idx_vector (r1, r2+1), octave::idx_vector (c1, c2+1));
 }
 
 ComplexMatrix
 ComplexMatrix::extract_n (octave_idx_type r1, octave_idx_type c1,
                           octave_idx_type nr, octave_idx_type nc) const
 {
-  return index (idx_vector (r1, r1 + nr), idx_vector (c1, c1 + nc));
+  return index (octave::idx_vector (r1, r1 + nr), octave::idx_vector (c1, c1 + nc));
 }
 
 // extract row or column i.
@@ -701,13 +701,13 @@
 ComplexRowVector
 ComplexMatrix::row (octave_idx_type i) const
 {
-  return index (idx_vector (i), idx_vector::colon);
+  return index (octave::idx_vector (i), octave::idx_vector::colon);
 }
 
 ComplexColumnVector
 ComplexMatrix::column (octave_idx_type i) const
 {
-  return index (idx_vector::colon, idx_vector (i));
+  return index (octave::idx_vector::colon, octave::idx_vector (i));
 }
 
 // Local function to calculate the 1-norm.
--- a/liboctave/array/CSparse.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/CSparse.h	Wed Apr 28 13:46:02 2021 -0400
@@ -88,8 +88,8 @@
   explicit SparseComplexMatrix (const ComplexNDArray& a)
     : MSparse<Complex> (a) { }
 
-  SparseComplexMatrix (const Array<Complex>& a, const idx_vector& r,
-                       const idx_vector& c, octave_idx_type nr = -1,
+  SparseComplexMatrix (const Array<Complex>& a, const octave::idx_vector& r,
+                       const octave::idx_vector& c, octave_idx_type nr = -1,
                        octave_idx_type nc = -1, bool sum_terms = true,
                        octave_idx_type nzm = -1)
     : MSparse<Complex> (a, r, c, nr, nc, sum_terms, nzm) { }
--- a/liboctave/array/MArray.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/MArray.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -53,7 +53,7 @@
 
 template <typename T>
 void
-MArray<T>::idx_add (const idx_vector& idx, T val)
+MArray<T>::idx_add (const octave::idx_vector& idx, T val)
 {
   octave_idx_type n = this->numel ();
   octave_idx_type ext = idx.extent (n);
@@ -71,7 +71,7 @@
 
 template <typename T>
 void
-MArray<T>::idx_add (const idx_vector& idx, const MArray<T>& vals)
+MArray<T>::idx_add (const octave::idx_vector& idx, const MArray<T>& vals)
 {
   octave_idx_type n = this->numel ();
   octave_idx_type ext = idx.extent (n);
@@ -100,7 +100,7 @@
 
 template <typename T>
 void
-MArray<T>::idx_min (const idx_vector& idx, const MArray<T>& vals)
+MArray<T>::idx_min (const octave::idx_vector& idx, const MArray<T>& vals)
 {
   octave_idx_type n = this->numel ();
   octave_idx_type ext = idx.extent (n);
@@ -119,7 +119,7 @@
 
 template <typename T>
 void
-MArray<T>::idx_max (const idx_vector& idx, const MArray<T>& vals)
+MArray<T>::idx_max (const octave::idx_vector& idx, const MArray<T>& vals)
 {
   octave_idx_type n = this->numel ();
   octave_idx_type ext = idx.extent (n);
@@ -137,8 +137,8 @@
 }
 
 template <typename T>
-void MArray<T>::idx_add_nd (const idx_vector& idx, const MArray<T>& vals,
-                            int dim)
+void MArray<T>::idx_add_nd (const octave::idx_vector& idx,
+                            const MArray<T>& vals, int dim)
 {
   int nd = std::max (this->ndims (), vals.ndims ());
   if (dim < 0)
--- a/liboctave/array/MArray.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/MArray.h	Wed Apr 28 13:46:02 2021 -0400
@@ -112,15 +112,15 @@
 
   //! Performs indexed accumulative addition.
   //@{
-  void idx_add (const idx_vector& idx, T val);
-  void idx_add (const idx_vector& idx, const MArray<T>& vals);
+  void idx_add (const octave::idx_vector& idx, T val);
+  void idx_add (const octave::idx_vector& idx, const MArray<T>& vals);
   //@}
 
-  void idx_min (const idx_vector& idx, const MArray<T>& vals);
+  void idx_min (const octave::idx_vector& idx, const MArray<T>& vals);
 
-  void idx_max (const idx_vector& idx, const MArray<T>& vals);
+  void idx_max (const octave::idx_vector& idx, const MArray<T>& vals);
 
-  void idx_add_nd (const idx_vector& idx, const MArray<T>& vals, int dim = -1);
+  void idx_add_nd (const octave::idx_vector& idx, const MArray<T>& vals, int dim = -1);
 
   void changesign (void);
 };
--- a/liboctave/array/MSparse.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/MSparse.h	Wed Apr 28 13:46:02 2021 -0400
@@ -58,7 +58,7 @@
   template <typename U>
   MSparse (const Sparse<U>& a) : Sparse<T> (a) { }
 
-  MSparse (const Array<T>& a, const idx_vector& r, const idx_vector& c,
+  MSparse (const Array<T>& a, const octave::idx_vector& r, const octave::idx_vector& c,
            octave_idx_type nr = -1, octave_idx_type nc = -1,
            bool sum_terms = true, octave_idx_type nzm = -1)
     : Sparse<T> (a, r, c, nr, nc, sum_terms, nzm) { }
--- a/liboctave/array/PermMatrix.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/PermMatrix.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -44,7 +44,7 @@
 {
   if (check)
     {
-      if (! idx_vector (p).is_permutation (p.numel ()))
+      if (! octave::idx_vector (p).is_permutation (p.numel ()))
         err_invalid_permutation ();
     }
 
@@ -59,7 +59,7 @@
 }
 
 void
-PermMatrix::setup (const idx_vector& idx, bool colp, octave_idx_type n)
+PermMatrix::setup (const octave::idx_vector& idx, bool colp, octave_idx_type n)
 {
   octave_idx_type len = idx.length (n);
 
@@ -74,7 +74,7 @@
     *this = this->transpose ();
 }
 
-PermMatrix::PermMatrix (const idx_vector& idx, bool colp, octave_idx_type n)
+PermMatrix::PermMatrix (const octave::idx_vector& idx, bool colp, octave_idx_type n)
   : Array<octave_idx_type> ()
 {
   setup (idx, colp, n);
@@ -220,7 +220,7 @@
   if (n != b.rows ())
     octave::err_nonconformant ("operator *", n, n, b.rows (), b.rows ());
 
-  r = PermMatrix (ia.index (idx_vector (ib)), true, false);
+  r = PermMatrix (ia.index (octave::idx_vector (ib)), true, false);
 
   return r;
 }
--- a/liboctave/array/PermMatrix.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/PermMatrix.h	Wed Apr 28 13:46:02 2021 -0400
@@ -50,7 +50,7 @@
 
   PermMatrix (const Array<octave_idx_type>& p, bool colp, bool check = true);
 
-  PermMatrix (const idx_vector& idx, bool colp, octave_idx_type n = 0);
+  PermMatrix (const octave::idx_vector& idx, bool colp, octave_idx_type n = 0);
 
   octave_idx_type dim1 (void) const
   { return Array<octave_idx_type>::numel (); }
@@ -120,7 +120,7 @@
 
   void setup (const Array<octave_idx_type>& p, bool colp, bool check);
 
-  void setup (const idx_vector& idx, bool colp, octave_idx_type n);
+  void setup (const octave::idx_vector& idx, bool colp, octave_idx_type n);
 };
 
 // Multiplying permutations together.
--- a/liboctave/array/Range.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Range.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -479,7 +479,7 @@
 };
 
 Array<double>
-Range::index (const idx_vector& i) const
+Range::index (const octave::idx_vector& i) const
 {
   Array<double> retval;
 
--- a/liboctave/array/Range.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Range.h	Wed Apr 28 13:46:02 2021 -0400
@@ -492,7 +492,7 @@
   double operator () (octave_idx_type i, octave_idx_type j) const
   { return elem (i, j); }
 
-  OCTAVE_API Array<double> index (const idx_vector& i) const;
+  OCTAVE_API Array<double> index (const octave::idx_vector& i) const;
 
   OCTAVE_API void set_base (double b);
 
--- a/liboctave/array/Sparse.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Sparse.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -301,8 +301,8 @@
 
 template <typename T>
 OCTAVE_API
-Sparse<T>::Sparse (const Array<T>& a, const idx_vector& r,
-                   const idx_vector& c, octave_idx_type nr,
+Sparse<T>::Sparse (const Array<T>& a, const octave::idx_vector& r,
+                   const octave::idx_vector& c, octave_idx_type nr,
                    octave_idx_type nc, bool sum_terms,
                    octave_idx_type nzm)
   : rep (nullptr), dimensions ()
@@ -362,7 +362,7 @@
       else if (cl == 1)
         {
           // Sparse column vector.  Sort row indices.
-          idx_vector rs = r.sorted ();
+          octave::idx_vector rs = r.sorted ();
 
           octave_quit ();
 
@@ -416,8 +416,8 @@
         }
       else
         {
-          idx_vector rr = r;
-          idx_vector cc = c;
+          octave::idx_vector rr = r;
+          octave::idx_vector cc = c;
           const octave_idx_type *rd = rr.raw ();
           const octave_idx_type *cd = cc.raw ();
           OCTAVE_LOCAL_BUFFER_INIT (octave_idx_type, ci, nc+1, 0);
@@ -510,7 +510,7 @@
     {
       // Sparse column vector.  Sort row indices.
       Array<octave_idx_type> rsi;
-      idx_vector rs = r.sorted (rsi);
+      octave::idx_vector rs = r.sorted (rsi);
 
       octave_quit ();
 
@@ -563,8 +563,8 @@
     }
   else
     {
-      idx_vector rr = r;
-      idx_vector cc = c;
+      octave::idx_vector rr = r;
+      octave::idx_vector cc = c;
       const octave_idx_type *rd = rr.raw ();
       const octave_idx_type *cd = cc.raw ();
       OCTAVE_LOCAL_BUFFER_INIT (octave_idx_type, ci, nc+1, 0);
@@ -1188,7 +1188,7 @@
 template <typename T>
 OCTAVE_API
 void
-Sparse<T>::delete_elements (const idx_vector& idx)
+Sparse<T>::delete_elements (const octave::idx_vector& idx)
 {
   Sparse<T> retval;
 
@@ -1231,7 +1231,7 @@
         {
           OCTAVE_LOCAL_BUFFER (octave_idx_type, ridx_new, nz);
           OCTAVE_LOCAL_BUFFER (T, data_new, nz);
-          idx_vector sidx = idx.sorted (true);
+          octave::idx_vector sidx = idx.sorted (true);
           const octave_idx_type *sj = sidx.raw ();
           octave_idx_type sl = sidx.length (nel);
           octave_idx_type nz_new = 0;
@@ -1280,7 +1280,7 @@
         *this = Sparse<T> ();
       else
         {
-          *this = index (idx_vector::colon);
+          *this = index (octave::idx_vector::colon);
           delete_elements (idx);
           *this = transpose (); // We want a row vector.
         }
@@ -1290,7 +1290,7 @@
 template <typename T>
 OCTAVE_API
 void
-Sparse<T>::delete_elements (const idx_vector& idx_i, const idx_vector& idx_j)
+Sparse<T>::delete_elements (const octave::idx_vector& idx_i, const octave::idx_vector& idx_j)
 {
   assert (ndims () == 2);
 
@@ -1357,8 +1357,8 @@
           else
             {
               // This is more memory-efficient than the approach below.
-              const Sparse<T> tmpl = index (idx_vector (0, lb), idx_j);
-              const Sparse<T> tmpu = index (idx_vector (ub, nr), idx_j);
+              const Sparse<T> tmpl = index (octave::idx_vector (0, lb), idx_j);
+              const Sparse<T> tmpu = index (octave::idx_vector (ub, nr), idx_j);
               *this = Sparse<T> (nr - (ub - lb), nc,
                                  tmpl.nnz () + tmpu.nnz ());
               for (octave_idx_type j = 0, k = 0; j < nc; j++)
@@ -1410,12 +1410,12 @@
 template <typename T>
 OCTAVE_API
 void
-Sparse<T>::delete_elements (int dim, const idx_vector& idx)
+Sparse<T>::delete_elements (int dim, const octave::idx_vector& idx)
 {
   if (dim == 0)
-    delete_elements (idx, idx_vector::colon);
+    delete_elements (idx, octave::idx_vector::colon);
   else if (dim == 1)
-    delete_elements (idx_vector::colon, idx);
+    delete_elements (octave::idx_vector::colon, idx);
   else
     (*current_liboctave_error_handler) ("invalid dimension in delete_elements");
 }
@@ -1423,7 +1423,7 @@
 template <typename T>
 OCTAVE_API
 Sparse<T>
-Sparse<T>::index (const idx_vector& idx, bool resize_ok) const
+Sparse<T>::index (const octave::idx_vector& idx, bool resize_ok) const
 {
   Sparse<T> retval;
 
@@ -1610,7 +1610,7 @@
           // I suppose this is rare (and it may easily overflow), so let's take
           // the easy way, and reshape first to column vector, which is already
           // handled above.
-          retval = index (idx_vector::colon).index (idx);
+          retval = index (octave::idx_vector::colon).index (idx);
           // In this case we're supposed to always inherit the shape, but
           // column(row) doesn't do it, so we'll do it instead.
           if (idx_dims(0) == 1 && idx_dims(1) != 1)
@@ -1624,7 +1624,7 @@
 template <typename T>
 OCTAVE_API
 Sparse<T>
-Sparse<T>::index (const idx_vector& idx_i, const idx_vector& idx_j,
+Sparse<T>::index (const octave::idx_vector& idx_i, const octave::idx_vector& idx_j,
                   bool resize_ok) const
 {
   Sparse<T> retval;
@@ -1817,7 +1817,7 @@
       else
         {
           // Get inverse permutation.
-          idx_vector idx_iinv = idx_i.inverse_permutation (nr);
+          octave::idx_vector idx_iinv = idx_i.inverse_permutation (nr);
           const octave_idx_type *iinv = idx_iinv.raw ();
 
           // Scatter buffer.
@@ -1853,14 +1853,14 @@
       // so we rely on the efficient transpose to handle this.
       // It may still make sense to optimize some cases here.
       retval = transpose ();
-      retval = retval.index (idx_vector::colon, idx_i);
+      retval = retval.index (octave::idx_vector::colon, idx_i);
       retval = retval.transpose ();
     }
   else
     {
       // A(I, J) is decomposed into A(:, J)(I, :).
-      retval = index (idx_vector::colon, idx_j);
-      retval = retval.index (idx_i, idx_vector::colon);
+      retval = index (octave::idx_vector::colon, idx_j);
+      retval = retval.index (idx_i, octave::idx_vector::colon);
     }
 
   return retval;
@@ -1869,7 +1869,7 @@
 template <typename T>
 OCTAVE_API
 void
-Sparse<T>::assign (const idx_vector& idx, const Sparse<T>& rhs)
+Sparse<T>::assign (const octave::idx_vector& idx, const Sparse<T>& rhs)
 {
   Sparse<T> retval;
 
@@ -1961,7 +1961,7 @@
           else if (idx.is_range () && idx.increment () == -1)
             {
               // It's s(u:-1:l) = r.  Reverse the assignment.
-              assign (idx.sorted (), rhs.index (idx_vector (rhl - 1, 0, -1)));
+              assign (idx.sorted (), rhs.index (octave::idx_vector (rhl - 1, 0, -1)));
             }
           else if (idx.is_permutation (n))
             {
@@ -1992,7 +1992,7 @@
               std::copy_n (tmp.data (), nz, new_data.fortran_vec ());
               // ... insert new data (densified) ...
               idx.copy_data (new_ri.fortran_vec () + nz);
-              new_data.assign (idx_vector (nz, new_nz), rhs.array_value ());
+              new_data.assign (octave::idx_vector (nz, new_nz), rhs.array_value ());
               // ... reassembly.
               *this = Sparse<T> (new_data, new_ri,
                                  static_cast<octave_idx_type> (0),
@@ -2002,8 +2002,8 @@
       else
         {
           dim_vector save_dims = dimensions;
-          *this = index (idx_vector::colon);
-          assign (idx, rhs.index (idx_vector::colon));
+          *this = index (octave::idx_vector::colon);
+          assign (idx, rhs.index (octave::idx_vector::colon));
           *this = reshape (save_dims);
         }
     }
@@ -2022,8 +2022,8 @@
 template <typename T>
 OCTAVE_API
 void
-Sparse<T>::assign (const idx_vector& idx_i,
-                   const idx_vector& idx_j, const Sparse<T>& rhs)
+Sparse<T>::assign (const octave::idx_vector& idx_i,
+                   const octave::idx_vector& idx_j, const Sparse<T>& rhs)
 {
   Sparse<T> retval;
 
@@ -2156,7 +2156,7 @@
             {
               // It's s(:,u:-1:l) = r.  Reverse the assignment.
               assign (idx_i, idx_j.sorted (),
-                      rhs.index (idx_i, idx_vector (m - 1, 0, -1)));
+                      rhs.index (idx_i, octave::idx_vector (m - 1, 0, -1)));
             }
           else if (idx_j.is_permutation (nc))
             {
@@ -2227,16 +2227,16 @@
               // especially for many small columns.  OTOH, transpose is an
               // efficient O(nr+nc+nnz) operation.
               *this = transpose ();
-              assign (idx_vector::colon, idx_i, rhs.transpose ());
+              assign (octave::idx_vector::colon, idx_i, rhs.transpose ());
               *this = transpose ();
             }
         }
       else
         {
           // Split it into 2 assignments and one indexing.
-          Sparse<T> tmp = index (idx_vector::colon, idx_j);
-          tmp.assign (idx_i, idx_vector::colon, rhs);
-          assign (idx_vector::colon, idx_j, tmp);
+          Sparse<T> tmp = index (octave::idx_vector::colon, idx_j);
+          tmp.assign (idx_i, octave::idx_vector::colon, rhs);
+          assign (octave::idx_vector::colon, idx_j, tmp);
         }
     }
   else if (m == 1 && n == 1)
@@ -2711,7 +2711,7 @@
               continue;
 
             octave_idx_type u = l + sparse_list[i].columns ();
-            retval.assign (idx_vector::colon, idx_vector (l, u),
+            retval.assign (octave::idx_vector::colon, octave::idx_vector (l, u),
                            sparse_list[i]);
             l = u;
           }
--- a/liboctave/array/Sparse.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/Sparse.h	Wed Apr 28 13:46:02 2021 -0400
@@ -37,7 +37,6 @@
 
 #include "Array.h"
 
-class idx_vector;
 class PermMatrix;
 
 // Two dimensional sparse class.  Handles the reference counting for
@@ -223,7 +222,7 @@
   OCTAVE_API Sparse (const Sparse<T>& a, const dim_vector& dv);
 
   OCTAVE_API
-  Sparse (const Array<T>& a, const idx_vector& r, const idx_vector& c,
+  Sparse (const Array<T>& a, const octave::idx_vector& r, const octave::idx_vector& c,
           octave_idx_type nr = -1, octave_idx_type nc = -1,
           bool sum_terms = true, octave_idx_type nzm = -1);
 
@@ -511,23 +510,23 @@
 
   octave_idx_type ndims (void) const { return dimensions.ndims (); }
 
-  OCTAVE_API void delete_elements (const idx_vector& i);
+  OCTAVE_API void delete_elements (const octave::idx_vector& i);
 
-  OCTAVE_API void delete_elements (int dim, const idx_vector& i);
+  OCTAVE_API void delete_elements (int dim, const octave::idx_vector& i);
 
-  OCTAVE_API void delete_elements (const idx_vector& i, const idx_vector& j);
+  OCTAVE_API void delete_elements (const octave::idx_vector& i, const octave::idx_vector& j);
 
   OCTAVE_API Sparse<T>
-  index (const idx_vector& i, bool resize_ok = false) const;
+  index (const octave::idx_vector& i, bool resize_ok = false) const;
 
   OCTAVE_API Sparse<T>
-  index (const idx_vector& i, const idx_vector& j,
+  index (const octave::idx_vector& i, const octave::idx_vector& j,
          bool resize_ok = false) const;
 
-  OCTAVE_API void assign (const idx_vector& i, const Sparse<T>& rhs);
+  OCTAVE_API void assign (const octave::idx_vector& i, const Sparse<T>& rhs);
 
   OCTAVE_API void
-  assign (const idx_vector& i, const idx_vector& j, const Sparse<T>& rhs);
+  assign (const octave::idx_vector& i, const octave::idx_vector& j, const Sparse<T>& rhs);
 
   OCTAVE_API void
   print_info (std::ostream& os, const std::string& prefix) const;
--- a/liboctave/array/boolSparse.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/boolSparse.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -180,8 +180,8 @@
           Array<octave_idx_type> tmp (dim_vector (nz, 1));
           std::copy_n (ridx (), nz, tmp.fortran_vec ());
           retval = Sparse<bool> (Array<bool> (dim_vector (1, 1), true),
-                                 idx_vector (tmp),
-                                 idx_vector (static_cast<octave_idx_type> (0)),
+                                 octave::idx_vector (tmp),
+                                 octave::idx_vector (static_cast<octave_idx_type> (0)),
                                  nr, 1, false);
         }
     }
@@ -231,8 +231,8 @@
           Array<octave_idx_type> tmp (dim_vector (nz, 1));
           std::copy_n (ridx (), nz, tmp.fortran_vec ());
           retval = Sparse<double> (Array<double> (dim_vector (1, 1), 1.0),
-                                   idx_vector (tmp),
-                                   idx_vector (static_cast<octave_idx_type> (0)),
+                                   octave::idx_vector (tmp),
+                                   octave::idx_vector (static_cast<octave_idx_type> (0)),
                                    nr, 1);
         }
     }
@@ -292,13 +292,13 @@
 }
 
 SparseBoolMatrix
-SparseBoolMatrix::index (const idx_vector& i, bool resize_ok) const
+SparseBoolMatrix::index (const octave::idx_vector& i, bool resize_ok) const
 {
   return Sparse<bool>::index (i, resize_ok);
 }
 
 SparseBoolMatrix
-SparseBoolMatrix::index (const idx_vector& i, const idx_vector& j,
+SparseBoolMatrix::index (const octave::idx_vector& i, const octave::idx_vector& j,
                          bool resize_ok) const
 {
   return Sparse<bool>::index (i, j, resize_ok);
--- a/liboctave/array/boolSparse.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/boolSparse.h	Wed Apr 28 13:46:02 2021 -0400
@@ -70,8 +70,8 @@
 
   explicit SparseBoolMatrix (const PermMatrix& a) : Sparse<bool> (a) { };
 
-  SparseBoolMatrix (const Array<bool>& a, const idx_vector& r,
-                    const idx_vector& c, octave_idx_type nr = -1,
+  SparseBoolMatrix (const Array<bool>& a, const octave::idx_vector& r,
+                    const octave::idx_vector& c, octave_idx_type nr = -1,
                     octave_idx_type nc = -1, bool sum_terms = true,
                     octave_idx_type nzm = -1)
     : Sparse<bool> (a, r, c, nr, nc, sum_terms, nzm) { }
@@ -108,9 +108,9 @@
 
   SparseBoolMatrix squeeze (void) const;
 
-  SparseBoolMatrix index (const idx_vector& i, bool resize_ok) const;
+  SparseBoolMatrix index (const octave::idx_vector& i, bool resize_ok) const;
 
-  SparseBoolMatrix index (const idx_vector& i, const idx_vector& j,
+  SparseBoolMatrix index (const octave::idx_vector& i, const octave::idx_vector& j,
                           bool resize_ok) const;
 
   SparseBoolMatrix reshape (const dim_vector& new_dims) const;
--- a/liboctave/array/dMatrix.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/dMatrix.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -400,14 +400,14 @@
   if (r1 > r2) { std::swap (r1, r2); }
   if (c1 > c2) { std::swap (c1, c2); }
 
-  return index (idx_vector (r1, r2+1), idx_vector (c1, c2+1));
+  return index (octave::idx_vector (r1, r2+1), octave::idx_vector (c1, c2+1));
 }
 
 Matrix
 Matrix::extract_n (octave_idx_type r1, octave_idx_type c1, octave_idx_type nr,
                    octave_idx_type nc) const
 {
-  return index (idx_vector (r1, r1 + nr), idx_vector (c1, c1 + nc));
+  return index (octave::idx_vector (r1, r1 + nr), octave::idx_vector (c1, c1 + nc));
 }
 
 // extract row or column i.
@@ -415,13 +415,13 @@
 RowVector
 Matrix::row (octave_idx_type i) const
 {
-  return index (idx_vector (i), idx_vector::colon);
+  return index (octave::idx_vector (i), octave::idx_vector::colon);
 }
 
 ColumnVector
 Matrix::column (octave_idx_type i) const
 {
-  return index (idx_vector::colon, idx_vector (i));
+  return index (octave::idx_vector::colon, octave::idx_vector (i));
 }
 
 // Local function to calculate the 1-norm.
--- a/liboctave/array/dSparse.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/dSparse.h	Wed Apr 28 13:46:02 2021 -0400
@@ -79,8 +79,8 @@
 
   explicit SparseMatrix (const NDArray& a) : MSparse<double> (a) { }
 
-  SparseMatrix (const Array<double>& a, const idx_vector& r,
-                const idx_vector& c, octave_idx_type nr = -1,
+  SparseMatrix (const Array<double>& a, const octave::idx_vector& r,
+                const octave::idx_vector& c, octave_idx_type nr = -1,
                 octave_idx_type nc = -1, bool sum_terms = true,
                 octave_idx_type nzm = -1)
     : MSparse<double> (a, r, c, nr, nc, sum_terms, nzm) { }
--- a/liboctave/array/fCMatrix.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/fCMatrix.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -689,14 +689,14 @@
   if (r1 > r2) { std::swap (r1, r2); }
   if (c1 > c2) { std::swap (c1, c2); }
 
-  return index (idx_vector (r1, r2+1), idx_vector (c1, c2+1));
+  return index (octave::idx_vector (r1, r2+1), octave::idx_vector (c1, c2+1));
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::extract_n (octave_idx_type r1, octave_idx_type c1,
                                octave_idx_type nr, octave_idx_type nc) const
 {
-  return index (idx_vector (r1, r1 + nr), idx_vector (c1, c1 + nc));
+  return index (octave::idx_vector (r1, r1 + nr), octave::idx_vector (c1, c1 + nc));
 }
 
 // extract row or column i.
@@ -704,13 +704,13 @@
 FloatComplexRowVector
 FloatComplexMatrix::row (octave_idx_type i) const
 {
-  return index (idx_vector (i), idx_vector::colon);
+  return index (octave::idx_vector (i), octave::idx_vector::colon);
 }
 
 FloatComplexColumnVector
 FloatComplexMatrix::column (octave_idx_type i) const
 {
-  return index (idx_vector::colon, idx_vector (i));
+  return index (octave::idx_vector::colon, octave::idx_vector (i));
 }
 
 // Local function to calculate the 1-norm.
--- a/liboctave/array/fMatrix.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/fMatrix.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -406,14 +406,14 @@
   if (r1 > r2) { std::swap (r1, r2); }
   if (c1 > c2) { std::swap (c1, c2); }
 
-  return index (idx_vector (r1, r2+1), idx_vector (c1, c2+1));
+  return index (octave::idx_vector (r1, r2+1), octave::idx_vector (c1, c2+1));
 }
 
 FloatMatrix
 FloatMatrix::extract_n (octave_idx_type r1, octave_idx_type c1,
                         octave_idx_type nr, octave_idx_type nc) const
 {
-  return index (idx_vector (r1, r1 + nr), idx_vector (c1, c1 + nc));
+  return index (octave::idx_vector (r1, r1 + nr), octave::idx_vector (c1, c1 + nc));
 }
 
 // extract row or column i.
@@ -421,13 +421,13 @@
 FloatRowVector
 FloatMatrix::row (octave_idx_type i) const
 {
-  return index (idx_vector (i), idx_vector::colon);
+  return index (octave::idx_vector (i), octave::idx_vector::colon);
 }
 
 FloatColumnVector
 FloatMatrix::column (octave_idx_type i) const
 {
-  return index (idx_vector::colon, idx_vector (i));
+  return index (octave::idx_vector::colon, octave::idx_vector (i));
 }
 
 // Local function to calculate the 1-norm.
--- a/liboctave/array/idx-vector.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/idx-vector.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -42,1270 +42,1238 @@
 #include "lo-error.h"
 #include "lo-mappers.h"
 
-OCTAVE_NORETURN static void
-err_invalid_range (void)
-{
-  (*current_liboctave_error_handler) ("invalid range used as index");
-}
-
-OCTAVE_NORETURN static void
-err_index_out_of_range (void)
-{
-  (*current_liboctave_error_handler)
-    ("internal error: idx_vector index out of range");
-}
-
-idx_vector::idx_vector_rep *
-idx_vector::nil_rep (void)
-{
-  static idx_vector_rep ivr;
-  return &ivr;
-}
-
-Array<octave_idx_type>
-idx_vector::idx_base_rep::as_array (void)
-{
-  (*current_liboctave_error_handler)
-    ("internal error: as_array not allowed for this index class");
-
-  // Never actually executed, but required to silence compiler warning
-  return Array<octave_idx_type> ();
-}
-
-idx_vector::idx_colon_rep::idx_colon_rep (char c)
-  : idx_base_rep ()
-{
-  if (c != ':')
-    (*current_liboctave_error_handler)
-      ("internal error: invalid character converted to idx_vector; must be ':'");
-}
-
-octave_idx_type
-idx_vector::idx_colon_rep::checkelem (octave_idx_type i) const
-{
-  if (i < 0)
-    err_index_out_of_range ();
-
-  return i;
-}
-
-idx_vector::idx_base_rep *
-idx_vector::idx_colon_rep::sort_idx (Array<octave_idx_type>&)
-{
-  (*current_liboctave_error_handler)
-    ("internal error: idx_colon_rep::sort_idx");
-}
-
-std::ostream&
-idx_vector::idx_colon_rep::print (std::ostream& os) const
-{
-  return os << ':';
-}
-
-idx_vector::idx_range_rep::idx_range_rep (octave_idx_type start,
-                                          octave_idx_type limit,
-                                          octave_idx_type step)
-  : idx_base_rep (), m_start(start),
-    m_len (step ? std::max ((limit - start) / step,
-                            static_cast<octave_idx_type> (0))
-               : -1),
-    m_step (step)
-{
-  if (m_len < 0)
-    err_invalid_range ();
-  if (m_start < 0)
-    octave::err_invalid_index (m_start);
-  if (m_step < 0 && m_start + (m_len-1)*m_step < 0)
-    octave::err_invalid_index (m_start + (m_len-1)*m_step);
-}
-
-idx_vector::idx_range_rep::idx_range_rep (const octave::range<double>& r)
-  : idx_base_rep (), m_start (0), m_len (r.numel ()), m_step (1)
-{
-  if (m_len < 0)
-    err_invalid_range ();
-
-  if (m_len > 0)
-    {
-      if (r.all_elements_are_ints ())
-        {
-          m_start = static_cast<octave_idx_type> (r.base ()) - 1;
-          m_step = static_cast<octave_idx_type> (r.increment ());
-          if (m_start < 0)
-            octave::err_invalid_index (m_start);
-          if (m_step < 0 && m_start + (m_len - 1)*m_step < 0)
-            octave::err_invalid_index (m_start + (m_len - 1)*m_step);
-        }
-      else
-        {
-          // find first non-integer, then gripe about it
-          double b = r.base ();
-          double inc = r.increment ();
-          octave::err_invalid_index (b != std::trunc (b) ? b : b + inc);
-        }
-    }
-}
-
-octave_idx_type
-idx_vector::idx_range_rep::checkelem (octave_idx_type i) const
-{
-  if (i < 0 || i >= m_len)
-    err_index_out_of_range ();
-
-  return m_start + i*m_step;
-}
-
-idx_vector::idx_base_rep *
-idx_vector::idx_range_rep::sort_uniq_clone (bool)
-{
-  if (m_step < 0)
-    return new idx_range_rep (m_start + (m_len - 1)*m_step, m_len, -m_step, DIRECT);
-  else
-    {
-      m_count++;
-      return this;
-    }
-}
-
-idx_vector::idx_base_rep *
-idx_vector::idx_range_rep::sort_idx (Array<octave_idx_type>& idx)
-{
-  if (m_step < 0 && m_len > 0)
-    {
-      idx.clear (1, m_len);
-      for (octave_idx_type i = 0; i < m_len; i++)
-        idx.xelem (i) = m_len - 1 - i;
-      return new idx_range_rep (m_start + (m_len - 1)*m_step, m_len, -m_step, DIRECT);
-    }
-  else
-    {
-      idx.clear (1, m_len);
-      for (octave_idx_type i = 0; i < m_len; i++)
-        idx.xelem (i) = i;
-      m_count++;
-      return this;
-    }
-}
-
-std::ostream&
-idx_vector::idx_range_rep::print (std::ostream& os) const
-{
-  os << m_start << ':' << m_step << ':' << m_start + m_len*m_step;
-  return os;
-}
-
-octave::range<double>
-idx_vector::idx_range_rep::unconvert (void) const
-{
-  return octave::range<double>::make_n_element_range
-    (static_cast<double> (m_start+1), static_cast<double> (m_step), m_len);
-}
-
-Array<octave_idx_type>
-idx_vector::idx_range_rep::as_array (void)
-{
-  Array<octave_idx_type> retval (dim_vector (1, m_len));
-  for (octave_idx_type i = 0; i < m_len; i++)
-    retval.xelem (i) = m_start + i*m_step;
-
-  return retval;
-}
-
-inline octave_idx_type
-convert_index (octave_idx_type i, octave_idx_type& ext)
-{
-  if (i <= 0)
-    octave::err_invalid_index (i-1);
-
-  if (ext < i)
-    ext = i;
-
-  return i - 1;
-}
-
-inline octave_idx_type
-convert_index (double x, octave_idx_type& ext)
-{
-  octave_idx_type i = static_cast<octave_idx_type> (x);
-
-  if (static_cast<double> (i) != x)
-    octave::err_invalid_index (x-1);
-
-  return convert_index (i, ext);
-}
-
-inline octave_idx_type
-convert_index (float x, octave_idx_type& ext)
-{
-  return convert_index (static_cast<double> (x), ext);
-}
-
-template <typename T>
-inline octave_idx_type
-convert_index (octave_int<T> x, octave_idx_type& ext)
-{
-  octave_idx_type i = octave_int<octave_idx_type> (x).value ();
-
-  return convert_index (i, ext);
-}
-
-template <typename T>
-idx_vector::idx_scalar_rep::idx_scalar_rep (T x)
-  : idx_base_rep (), m_data (0)
-{
-  octave_idx_type dummy = 0;
-
-  m_data = convert_index (x, dummy);
-}
-
-idx_vector::idx_scalar_rep::idx_scalar_rep (octave_idx_type i)
-  : idx_base_rep (), m_data (i)
-{
-  if (m_data < 0)
-    octave::err_invalid_index (m_data);
-}
-
-octave_idx_type
-idx_vector::idx_scalar_rep::checkelem (octave_idx_type i) const
+namespace octave
 {
-  if (i != 0)
-    err_index_out_of_range ();
-
-  return m_data;
-}
-
-idx_vector::idx_base_rep *
-idx_vector::idx_scalar_rep::sort_idx (Array<octave_idx_type>& idx)
-{
-  idx.clear (1, 1);
-  idx.fill (0);
-  m_count++;
-  return this;
-}
-
-std::ostream& idx_vector::idx_scalar_rep::print (std::ostream& os) const
-{
-  return os << m_data;
-}
-
-double
-idx_vector::idx_scalar_rep::unconvert (void) const
-{
-  return m_data + 1;
-}
-
-Array<octave_idx_type>
-idx_vector::idx_scalar_rep::as_array (void)
-{
-  return Array<octave_idx_type> (dim_vector (1, 1), m_data);
-}
-
-template <typename T>
-idx_vector::idx_vector_rep::idx_vector_rep (const Array<T>& nda)
-  : idx_base_rep (), m_data (nullptr), m_len (nda.numel ()), m_ext (0),
-    m_aowner (nullptr), m_orig_dims (nda.dims ())
-{
-  if (m_len != 0)
-    {
-      std::unique_ptr<octave_idx_type []> d (new octave_idx_type [m_len]);
-
-      for (octave_idx_type i = 0; i < m_len; i++)
-        d[i] = convert_index (nda.xelem (i), m_ext);
-
-      m_data = d.release ();
-    }
-}
-
-// Note that this makes a shallow copy of the index array.
+  OCTAVE_NORETURN static void err_invalid_range (void)
+  {
+    (*current_liboctave_error_handler) ("invalid range used as index");
+  }
 
-idx_vector::idx_vector_rep::idx_vector_rep (const Array<octave_idx_type>& inda)
-  : idx_base_rep (), m_data (inda.data ()), m_len (inda.numel ()), m_ext (0),
-    m_aowner (new Array<octave_idx_type> (inda)), m_orig_dims (inda.dims ())
-{
-  if (m_len != 0)
-    {
-      octave_idx_type max = -1;
-      for (octave_idx_type i = 0; i < m_len; i++)
-        {
-          octave_idx_type k = inda.xelem (i);
-          if (k < 0)
-            octave::err_invalid_index (k);
-          else if (k > max)
-            max = k;
-        }
-
-      m_ext = max + 1;
-    }
-}
+  OCTAVE_NORETURN static void err_index_out_of_range (void)
+  {
+    (*current_liboctave_error_handler)
+      ("internal error: idx_vector index out of range");
+  }
 
-idx_vector::idx_vector_rep::idx_vector_rep (const Array<octave_idx_type>& inda,
-                                            octave_idx_type ext, direct)
-  : idx_base_rep (), m_data (inda.data ()), m_len (inda.numel ()),
-    m_ext (ext), m_aowner (new Array<octave_idx_type> (inda)),
-    m_orig_dims (inda.dims ())
-{
-  // No checking.
-  if (m_ext < 0)
-    {
-      octave_idx_type max = -1;
-      for (octave_idx_type i = 0; i < m_len; i++)
-        if (m_data[i] > max)
-          max = m_data[i];
-
-      m_ext = max + 1;
-    }
-}
-
-idx_vector::idx_vector_rep::idx_vector_rep (bool b)
-  : idx_base_rep (), m_data (nullptr), m_len (b ? 1 : 0), m_ext (0),
-    m_aowner (nullptr), m_orig_dims (m_len, m_len)
-{
-  if (m_len != 0)
-    {
-      octave_idx_type *d = new octave_idx_type [1];
-      d[0] = 0;
-      m_data = d;
-      m_ext = 1;
-    }
-}
-
-idx_vector::idx_vector_rep::idx_vector_rep (const Array<bool>& bnda,
-                                            octave_idx_type nnz)
-  : idx_base_rep (), m_data (nullptr), m_len (nnz), m_ext (0),
-    m_aowner (nullptr), m_orig_dims ()
-{
-  if (nnz < 0)
-    m_len = bnda.nnz ();
-
-  const dim_vector dv = bnda.dims ();
-
-  m_orig_dims = dv.make_nd_vector (m_len);
+  idx_vector::idx_vector_rep * idx_vector::nil_rep (void)
+  {
+    static idx_vector_rep ivr;
+    return &ivr;
+  }
 
-  if (m_len != 0)
-    {
-      octave_idx_type *d = new octave_idx_type [m_len];
-
-      octave_idx_type ntot = bnda.numel ();
-
-      octave_idx_type k = 0;
-      for (octave_idx_type i = 0; i < ntot; i++)
-        if (bnda.xelem (i))
-          d[k++] = i;
-
-      m_data = d;
-
-      m_ext = d[k-1] + 1;
-    }
-}
-
-idx_vector::idx_vector_rep::idx_vector_rep (const Sparse<bool>& bnda)
-  : idx_base_rep (), m_data (nullptr), m_len (bnda.nnz ()), m_ext (0),
-    m_aowner (nullptr), m_orig_dims ()
-{
-  const dim_vector dv = bnda.dims ();
-
-  m_orig_dims = dv.make_nd_vector (m_len);
-
-  if (m_len != 0)
-    {
-      octave_idx_type *d = new octave_idx_type [m_len];
+  Array<octave_idx_type> idx_vector::idx_base_rep::as_array (void)
+  {
+    (*current_liboctave_error_handler)
+      ("internal error: as_array not allowed for this index class");
 
-      octave_idx_type k = 0;
-      octave_idx_type nc = bnda.cols ();
-      octave_idx_type nr = bnda.rows ();
-
-      for (octave_idx_type j = 0; j < nc; j++)
-        for (octave_idx_type i = bnda.cidx (j); i < bnda.cidx (j+1); i++)
-          if (bnda.data (i))
-            d[k++] = j * nr + bnda.ridx (i);
-
-      m_data = d;
-
-      m_ext = d[k-1] + 1;
-    }
-}
-
-idx_vector::idx_vector_rep::~idx_vector_rep (void)
-{
-  if (m_aowner)
-    delete m_aowner;
-  else
-    delete [] m_data;
-}
-
-octave_idx_type
-idx_vector::idx_vector_rep::checkelem (octave_idx_type n) const
-{
-  if (n < 0 || n >= m_len)
-    octave::err_invalid_index (n);
+    // Never actually executed, but required to silence compiler warning
+    return Array<octave_idx_type> ();
+  }
 
-  return xelem (n);
-}
-
-idx_vector::idx_base_rep *
-idx_vector::idx_vector_rep::sort_uniq_clone (bool uniq)
-{
-  if (m_len == 0)
-    {
-      m_count++;
-      return this;
-    }
-
-  // This is wrapped in unique_ptr so that we don't leak on out-of-memory.
-  std::unique_ptr<idx_vector_rep> new_rep
-    (new idx_vector_rep (nullptr, m_len, m_ext, m_orig_dims, DIRECT));
-
-  if (m_ext > m_len*octave::math::log2 (1.0 + m_len))
-    {
-      // Use standard sort via octave_sort.
-      octave_idx_type *new_data = new octave_idx_type [m_len];
-      new_rep->m_data = new_data;
-
-      std::copy_n (m_data, m_len, new_data);
-      octave_sort<octave_idx_type> lsort;
-      lsort.set_compare (ASCENDING);
-      lsort.sort (new_data, m_len);
+  idx_vector::idx_colon_rep::idx_colon_rep (char c)
+    : idx_base_rep ()
+  {
+    if (c != ':')
+      (*current_liboctave_error_handler)
+        ("internal error: invalid character converted to idx_vector; must be ':'");
+  }
 
-      if (uniq)
-        {
-          octave_idx_type new_len = std::unique (new_data, new_data + m_len)
-                                    - new_data;
-          new_rep->m_len = new_len;
-          if (new_rep->m_orig_dims.ndims () == 2 && new_rep->m_orig_dims(0) == 1)
-            new_rep->m_orig_dims = dim_vector (1, new_len);
-          else
-            new_rep->m_orig_dims = dim_vector (new_len, 1);
-        }
-    }
-  else if (uniq)
-    {
-      // Use two-pass bucket sort (only a mask array needed).
-      OCTAVE_LOCAL_BUFFER_INIT (bool, has, m_ext, false);
-      for (octave_idx_type i = 0; i < m_len; i++)
-        has[m_data[i]] = true;
+  octave_idx_type
+  idx_vector::idx_colon_rep::checkelem (octave_idx_type i) const
+  {
+    if (i < 0)
+      err_index_out_of_range ();
 
-      octave_idx_type new_len = 0;
-      for (octave_idx_type i = 0; i < m_ext; i++)
-        new_len += has[i];
-
-      new_rep->m_len = new_len;
-      if (new_rep->m_orig_dims.ndims () == 2 && new_rep->m_orig_dims(0) == 1)
-        new_rep->m_orig_dims = dim_vector (1, new_len);
-      else
-        new_rep->m_orig_dims = dim_vector (new_len, 1);
-
-      octave_idx_type *new_data = new octave_idx_type [new_len];
-      new_rep->m_data = new_data;
+    return i;
+  }
 
-      for (octave_idx_type i = 0, j = 0; i < m_ext; i++)
-        if (has[i])
-          new_data[j++] = i;
-    }
-  else
-    {
-      // Use two-pass bucket sort.
-      OCTAVE_LOCAL_BUFFER_INIT (octave_idx_type, cnt, m_ext, 0);
-      for (octave_idx_type i = 0; i < m_len; i++)
-        cnt[m_data[i]]++;
-
-      octave_idx_type *new_data = new octave_idx_type [m_len];
-      new_rep->m_data = new_data;
-
-      for (octave_idx_type i = 0, j = 0; i < m_ext; i++)
-        {
-          for (octave_idx_type k = 0; k < cnt[i]; k++)
-            new_data[j++] = i;
-        }
-    }
-
-  return new_rep.release ();
-}
-
-idx_vector::idx_base_rep *
-idx_vector::idx_vector_rep::sort_idx (Array<octave_idx_type>& idx)
-{
-  // This is wrapped in unique_ptr so that we don't leak on out-of-memory.
-  std::unique_ptr<idx_vector_rep> new_rep
-    (new idx_vector_rep (nullptr, m_len, m_ext, m_orig_dims, DIRECT));
-
-  if (m_ext > m_len*octave::math::log2 (1.0 + m_len))
-    {
-      // Use standard sort via octave_sort.
-      idx.clear (m_orig_dims);
-      octave_idx_type *idx_data = idx.fortran_vec ();
-      for (octave_idx_type i = 0; i < m_len; i++)
-        idx_data[i] = i;
-
-      octave_idx_type *new_data = new octave_idx_type [m_len];
-      new_rep->m_data = new_data;
-      std::copy_n (m_data, m_len, new_data);
-
-      octave_sort<octave_idx_type> lsort;
-      lsort.set_compare (ASCENDING);
-      lsort.sort (new_data, idx_data, m_len);
-    }
-  else
-    {
-      // Use two-pass bucket sort.
-      OCTAVE_LOCAL_BUFFER_INIT (octave_idx_type, cnt, m_ext, 0);
-
-      for (octave_idx_type i = 0; i < m_len; i++)
-        cnt[m_data[i]]++;
-
-      idx.clear (m_orig_dims);
-      octave_idx_type *idx_data = idx.fortran_vec ();
-
-      octave_idx_type *new_data = new octave_idx_type [m_len];
-      new_rep->m_data = new_data;
-
-      for (octave_idx_type i = 0, k = 0; i < m_ext; i++)
-        {
-          octave_idx_type j = cnt[i];
-          cnt[i] = k;
-          k += j;
-        }
-
-      for (octave_idx_type i = 0; i < m_len; i++)
-        {
-          octave_idx_type j = m_data[i];
-          octave_idx_type k = cnt[j]++;
-          new_data[k] = j;
-          idx_data[k] = i;
-        }
-    }
-
-  return new_rep.release ();
-}
-
-std::ostream&
-idx_vector::idx_vector_rep::print (std::ostream& os) const
-{
-  os << '[';
-
-  for (octave_idx_type i = 0; i < m_len - 1; i++)
-    os << m_data[i] << ',' << ' ';
-
-  if (m_len > 0)
-    os << m_data[m_len-1];
-
-  os << ']';
-
-  return os;
-}
-
-Array<double>
-idx_vector::idx_vector_rep::unconvert (void) const
-{
-  Array<double> retval (m_orig_dims);
-  for (octave_idx_type i = 0; i < m_len; i++)
-    retval.xelem (i) = m_data[i] + 1;
-  return retval;
-}
+  idx_vector::idx_base_rep *
+  idx_vector::idx_colon_rep::sort_idx (Array<octave_idx_type>&)
+  {
+    (*current_liboctave_error_handler)
+      ("internal error: idx_colon_rep::sort_idx");
+  }
 
-Array<octave_idx_type>
-idx_vector::idx_vector_rep::as_array (void)
-{
-  if (m_aowner)
-    return *m_aowner;
-  else
-    {
-      Array<octave_idx_type> retval (m_orig_dims);
-
-      if (m_data)
-        {
-          std::memcpy (retval.fortran_vec (), m_data, m_len*sizeof (octave_idx_type));
-          // Delete the old copy and share the m_data instead to save memory.
-          delete [] m_data;
-        }
-
-      m_data = retval.fortran_vec ();
-      m_aowner = new Array<octave_idx_type> (retval);
-
-      return retval;
-    }
-}
-
-idx_vector::idx_mask_rep::idx_mask_rep (bool b)
-  : idx_base_rep (), m_data (nullptr), m_len (b ? 1 : 0), m_ext (0),
-    m_lsti (-1), m_lste (-1), m_aowner (nullptr), m_orig_dims (m_len, m_len)
-{
-  if (m_len != 0)
-    {
-      bool *d = new bool [1];
-      d[0] = true;
-      m_data = d;
-      m_ext = 1;
-    }
-}
-
-idx_vector::idx_mask_rep::idx_mask_rep (const Array<bool>& bnda,
-                                        octave_idx_type nnz)
-  : idx_base_rep (), m_data (nullptr), m_len (nnz), m_ext (bnda.numel ()),
-    m_lsti (-1), m_lste (-1), m_aowner (nullptr), m_orig_dims ()
-{
-  if (nnz < 0)
-    m_len = bnda.nnz ();
-
-  // We truncate the extent as much as possible.  For Matlab
-  // compatibility, but maybe it's not a bad idea anyway.
-  while (m_ext > 0 && ! bnda(m_ext-1))
-    m_ext--;
-
-  const dim_vector dv = bnda.dims ();
-
-  m_orig_dims = dv.make_nd_vector (m_len);
-
-  m_aowner = new Array<bool> (bnda);
-  m_data = bnda.data ();
-}
-
-idx_vector::idx_mask_rep::~idx_mask_rep (void)
-{
-  if (m_aowner)
-    delete m_aowner;
-  else
-    delete [] m_data;
-}
-
-octave_idx_type
-idx_vector::idx_mask_rep::xelem (octave_idx_type n) const
-{
-  if (n == m_lsti + 1)
-    {
-      m_lsti = n;
-      while (! m_data[++m_lste]) ;
-    }
-  else
-    {
-      m_lsti = n++;
-      m_lste = -1;
-      while (n > 0)
-        if (m_data[++m_lste]) --n;
-    }
-  return m_lste;
-}
-
-octave_idx_type
-idx_vector::idx_mask_rep::checkelem (octave_idx_type n) const
-{
-  if (n < 0 || n >= m_len)
-    octave::err_invalid_index (n);
-
-  return xelem (n);
-}
-
-std::ostream&
-idx_vector::idx_mask_rep::print (std::ostream& os) const
-{
-  os << '[';
-
-  for (octave_idx_type i = 0; i < m_ext - 1; i++)
-    os << m_data[i] << ',' << ' ';
-
-  if (m_ext > 0)
-    os << m_data[m_ext-1];
-
-  os << ']';
-
-  return os;
-}
-
-Array<bool>
-idx_vector::idx_mask_rep::unconvert (void) const
-{
-  if (m_aowner)
-    return *m_aowner;
-  else
-    {
-      Array<bool> retval (dim_vector (m_ext, 1));
-      for (octave_idx_type i = 0; i < m_ext; i++)
-        retval.xelem (i) = m_data[i];
-      return retval;
-    }
-}
+  std::ostream& idx_vector::idx_colon_rep::print (std::ostream& os) const
+  {
+    return os << ':';
+  }
 
-Array<octave_idx_type>
-idx_vector::idx_mask_rep::as_array (void)
-{
-  if (m_aowner)
-    return m_aowner->find ().reshape (m_orig_dims);
-  else
-    {
-      Array<bool> retval (m_orig_dims);
-      for (octave_idx_type i = 0, j = 0; i < m_ext; i++)
-        if (m_data[i])
-          retval.xelem (j++) = i;
-
-      return retval;
-    }
-}
-
-idx_vector::idx_base_rep *
-idx_vector::idx_mask_rep::sort_idx (Array<octave_idx_type>& idx)
-{
-  idx.clear (m_len, 1);
-  for (octave_idx_type i = 0; i < m_len; i++)
-    idx.xelem (i) = i;
-
-  m_count++;
-  return this;
-}
-
-const idx_vector idx_vector::colon (new idx_vector::idx_colon_rep ());
-
-idx_vector::idx_vector (const Array<bool>& bnda)
-  : m_rep (nullptr)
-{
-  // Convert only if it means saving at least half the memory.
-  static const int factor = (2 * sizeof (octave_idx_type));
-  octave_idx_type nnz = bnda.nnz ();
-  if (nnz <= bnda.numel () / factor)
-    m_rep = new idx_vector_rep (bnda, nnz);
-  else
-    m_rep = new idx_mask_rep (bnda, nnz);
-}
-
-bool
-idx_vector::maybe_reduce (octave_idx_type n, const idx_vector& j,
-                          octave_idx_type nj)
-{
-  bool reduced = false;
-
-  // Empty index always reduces.
-  if (m_rep->length (n) == 0)
-    {
-      *this = idx_vector ();
-      return true;
-    }
+  idx_vector::idx_range_rep::idx_range_rep (octave_idx_type start,
+                                            octave_idx_type limit,
+                                            octave_idx_type step)
+    : idx_base_rep (), m_start(start),
+      m_len (step ? std::max ((limit - start) / step,
+                              static_cast<octave_idx_type> (0))
+             : -1),
+      m_step (step)
+  {
+    if (m_len < 0)
+      err_invalid_range ();
+    if (m_start < 0)
+      err_invalid_index (m_start);
+    if (m_step < 0 && m_start + (m_len-1)*m_step < 0)
+      err_invalid_index (m_start + (m_len-1)*m_step);
+  }
 
-  // Possibly skip singleton dims.
-  if (n == 1 && m_rep->is_colon_equiv (n))
-    {
-      *this = j;
-      return true;
-    }
-
-  if (nj == 1 && j.is_colon_equiv (nj))
-    return true;
-
-  switch (j.idx_class ())
-    {
-    case class_colon:
-      switch (m_rep->idx_class ())
-        {
-        case class_colon:
-          // (:,:) reduces to (:)
-          reduced = true;
-          break;
+  idx_vector::idx_range_rep::idx_range_rep (const range<double>& r)
+    : idx_base_rep (), m_start (0), m_len (r.numel ()), m_step (1)
+  {
+    if (m_len < 0)
+      err_invalid_range ();
 
-        case class_scalar:
-          {
-            // (i,:) reduces to a range.
-            idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
-            octave_idx_type k = r->get_data ();
-            *this = new idx_range_rep (k, nj, n, DIRECT);
-            reduced = true;
-          }
-          break;
-
-        case class_range:
-          {
-            // (i:k:end,:) reduces to a range if i <= k and k divides n.
-            idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
-            octave_idx_type s = r->get_start ();
-            octave_idx_type l = r->length (n);
-            octave_idx_type t = r->get_step ();
-            if (l*t == n)
-              {
-                *this = new idx_range_rep (s, l * nj, t, DIRECT);
-                reduced = true;
-              }
-          }
-          break;
-
-        default:
-          break;
-        }
-      break;
-
-    case class_range:
-      switch (m_rep->idx_class ())
-        {
-        case class_colon:
+    if (m_len > 0)
+      {
+        if (r.all_elements_are_ints ())
           {
-            // (:,i:j) reduces to a range (the m_step must be 1)
-            idx_range_rep *rj = dynamic_cast<idx_range_rep *> (j.m_rep);
-            if (rj->get_step () == 1)
-              {
-                octave_idx_type sj = rj->get_start ();
-                octave_idx_type lj = rj->length (nj);
-                *this = new idx_range_rep (sj * n, lj * n, 1, DIRECT);
-                reduced = true;
-              }
-          }
-          break;
-
-        case class_scalar:
-          {
-            // (k,i:d:j) reduces to a range.
-            idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
-            idx_range_rep *rj = dynamic_cast<idx_range_rep *> (j.m_rep);
-            octave_idx_type k = r->get_data ();
-            octave_idx_type sj = rj->get_start ();
-            octave_idx_type lj = rj->length (nj);
-            octave_idx_type tj = rj->get_step ();
-            *this = new idx_range_rep (n * sj + k, lj, n * tj, DIRECT);
-            reduced = true;
+            m_start = static_cast<octave_idx_type> (r.base ()) - 1;
+            m_step = static_cast<octave_idx_type> (r.increment ());
+            if (m_start < 0)
+              err_invalid_index (m_start);
+            if (m_step < 0 && m_start + (m_len - 1)*m_step < 0)
+              err_invalid_index (m_start + (m_len - 1)*m_step);
           }
-          break;
-
-        case class_range:
-          {
-            // (i:k:end,p:q) reduces to a range if i <= k and k divides n.
-            // (ones (1, m), ones (1, n)) reduces to (ones (1, m*n))
-            idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
-            octave_idx_type s = r->get_start ();
-            octave_idx_type l = r->length (n);
-            octave_idx_type t = r->get_step ();
-            idx_range_rep *rj = dynamic_cast<idx_range_rep *> (j.m_rep);
-            octave_idx_type sj = rj->get_start ();
-            octave_idx_type lj = rj->length (nj);
-            octave_idx_type tj = rj->get_step ();
-            if ((l*t == n && tj == 1) || (t == 0 && tj == 0))
-              {
-                *this = new idx_range_rep (s + n * sj, l * lj, t, DIRECT);
-                reduced = true;
-              }
-          }
-          break;
-
-        default:
-          break;
-        }
-      break;
-
-    case class_scalar:
-      switch (m_rep->idx_class ())
-        {
-        case class_scalar:
+        else
           {
-            // (i,j) reduces to a single index.
-            idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
-            idx_scalar_rep *rj = dynamic_cast<idx_scalar_rep *> (j.m_rep);
-            octave_idx_type k = r->get_data () + n * rj->get_data ();
-            *this = new idx_scalar_rep (k, DIRECT);
-            reduced = true;
-          }
-          break;
-
-        case class_range:
-          {
-            // (i:d:j,k) reduces to a range.
-            idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
-            idx_scalar_rep *rj = dynamic_cast<idx_scalar_rep *> (j.m_rep);
-            octave_idx_type s = r->get_start ();
-            octave_idx_type l = r->length (nj);
-            octave_idx_type t = r->get_step ();
-            octave_idx_type k = rj->get_data ();
-            *this = new idx_range_rep (n * k + s, l, t, DIRECT);
-            reduced = true;
-          }
-          break;
-
-        case class_colon:
-          {
-            // (:,k) reduces to a range.
-            idx_scalar_rep *rj = dynamic_cast<idx_scalar_rep *> (j.m_rep);
-            octave_idx_type k = rj->get_data ();
-            *this = new idx_range_rep (n * k, n, 1, DIRECT);
-            reduced = true;
-          }
-          break;
-
-        default:
-          break;
-        }
-      break;
-
-    default:
-      break;
-    }
-
-  return reduced;
-}
-
-bool
-idx_vector::is_cont_range (octave_idx_type n,
-                           octave_idx_type& l, octave_idx_type& u) const
-{
-  bool res = false;
-
-  switch (m_rep->idx_class ())
-    {
-    case class_colon:
-      l = 0; u = n;
-      res = true;
-      break;
-
-    case class_range:
-      {
-        idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
-        if (r->get_step () == 1)
-          {
-            l = r->get_start ();
-            u = l + r->length (n);
-            res = true;
+            // find first non-integer, then gripe about it
+            double b = r.base ();
+            double inc = r.increment ();
+            err_invalid_index (b != std::trunc (b) ? b : b + inc);
           }
       }
-      break;
+  }
+
+  octave_idx_type
+  idx_vector::idx_range_rep::checkelem (octave_idx_type i) const
+  {
+    if (i < 0 || i >= m_len)
+      err_index_out_of_range ();
+
+    return m_start + i*m_step;
+  }
 
-    case class_scalar:
+  idx_vector::idx_base_rep * idx_vector::idx_range_rep::sort_uniq_clone (bool)
+  {
+    if (m_step < 0)
+      return new idx_range_rep (m_start + (m_len - 1)*m_step, m_len, -m_step, DIRECT);
+    else
+      {
+        m_count++;
+        return this;
+      }
+  }
+
+  idx_vector::idx_base_rep *
+  idx_vector::idx_range_rep::sort_idx (Array<octave_idx_type>& idx)
+  {
+    if (m_step < 0 && m_len > 0)
+      {
+        idx.clear (1, m_len);
+        for (octave_idx_type i = 0; i < m_len; i++)
+          idx.xelem (i) = m_len - 1 - i;
+        return new idx_range_rep (m_start + (m_len - 1)*m_step, m_len, -m_step, DIRECT);
+      }
+    else
       {
-        idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
-        l = r->get_data ();
-        u = l + 1;
-        res = true;
+        idx.clear (1, m_len);
+        for (octave_idx_type i = 0; i < m_len; i++)
+          idx.xelem (i) = i;
+        m_count++;
+        return this;
       }
-      break;
+  }
+
+  std::ostream& idx_vector::idx_range_rep::print (std::ostream& os) const
+  {
+    os << m_start << ':' << m_step << ':' << m_start + m_len*m_step;
+    return os;
+  }
+
+  range<double> idx_vector::idx_range_rep::unconvert (void) const
+  {
+    return range<double>::make_n_element_range
+      (static_cast<double> (m_start+1), static_cast<double> (m_step), m_len);
+  }
+
+  Array<octave_idx_type> idx_vector::idx_range_rep::as_array (void)
+  {
+    Array<octave_idx_type> retval (dim_vector (1, m_len));
+    for (octave_idx_type i = 0; i < m_len; i++)
+      retval.xelem (i) = m_start + i*m_step;
+
+    return retval;
+  }
+
+  inline octave_idx_type convert_index (octave_idx_type i, octave_idx_type& ext)
+  {
+    if (i <= 0)
+      err_invalid_index (i-1);
+
+    if (ext < i)
+      ext = i;
+
+    return i - 1;
+  }
+
+  inline octave_idx_type convert_index (double x, octave_idx_type& ext)
+  {
+    octave_idx_type i = static_cast<octave_idx_type> (x);
+
+    if (static_cast<double> (i) != x)
+      err_invalid_index (x-1);
+
+    return convert_index (i, ext);
+  }
+
+  inline octave_idx_type convert_index (float x, octave_idx_type& ext)
+  {
+    return convert_index (static_cast<double> (x), ext);
+  }
+
+  template <typename T>
+  inline octave_idx_type convert_index (octave_int<T> x, octave_idx_type& ext)
+  {
+    octave_idx_type i = octave_int<octave_idx_type> (x).value ();
+
+    return convert_index (i, ext);
+  }
+
+  template <typename T>
+  idx_vector::idx_scalar_rep::idx_scalar_rep (T x)
+    : idx_base_rep (), m_data (0)
+  {
+    octave_idx_type dummy = 0;
+
+    m_data = convert_index (x, dummy);
+  }
+
+  idx_vector::idx_scalar_rep::idx_scalar_rep (octave_idx_type i)
+    : idx_base_rep (), m_data (i)
+  {
+    if (m_data < 0)
+      err_invalid_index (m_data);
+  }
+
+  octave_idx_type
+  idx_vector::idx_scalar_rep::checkelem (octave_idx_type i) const
+  {
+    if (i != 0)
+      err_index_out_of_range ();
+
+    return m_data;
+  }
+
+  idx_vector::idx_base_rep *
+  idx_vector::idx_scalar_rep::sort_idx (Array<octave_idx_type>& idx)
+  {
+    idx.clear (1, 1);
+    idx.fill (0);
+    m_count++;
+    return this;
+  }
+
+  std::ostream& idx_vector::idx_scalar_rep::print (std::ostream& os) const
+  {
+    return os << m_data;
+  }
+
+  double idx_vector::idx_scalar_rep::unconvert (void) const
+  {
+    return m_data + 1;
+  }
+
+  Array<octave_idx_type> idx_vector::idx_scalar_rep::as_array (void)
+  {
+    return Array<octave_idx_type> (dim_vector (1, 1), m_data);
+  }
+
+  template <typename T>
+  idx_vector::idx_vector_rep::idx_vector_rep (const Array<T>& nda)
+    : idx_base_rep (), m_data (nullptr), m_len (nda.numel ()), m_ext (0),
+      m_aowner (nullptr), m_orig_dims (nda.dims ())
+  {
+    if (m_len != 0)
+      {
+        std::unique_ptr<octave_idx_type []> d (new octave_idx_type [m_len]);
+
+        for (octave_idx_type i = 0; i < m_len; i++)
+          d[i] = convert_index (nda.xelem (i), m_ext);
+
+        m_data = d.release ();
+      }
+  }
+
+  // Note that this makes a shallow copy of the index array.
+
+  idx_vector::idx_vector_rep::idx_vector_rep (const Array<octave_idx_type>& inda)
+    : idx_base_rep (), m_data (inda.data ()), m_len (inda.numel ()), m_ext (0),
+      m_aowner (new Array<octave_idx_type> (inda)), m_orig_dims (inda.dims ())
+  {
+    if (m_len != 0)
+      {
+        octave_idx_type max = -1;
+        for (octave_idx_type i = 0; i < m_len; i++)
+          {
+            octave_idx_type k = inda.xelem (i);
+            if (k < 0)
+              err_invalid_index (k);
+            else if (k > max)
+              max = k;
+          }
+
+        m_ext = max + 1;
+      }
+  }
+
+  idx_vector::idx_vector_rep::idx_vector_rep (const Array<octave_idx_type>& inda,
+                                              octave_idx_type ext, direct)
+    : idx_base_rep (), m_data (inda.data ()), m_len (inda.numel ()),
+      m_ext (ext), m_aowner (new Array<octave_idx_type> (inda)),
+      m_orig_dims (inda.dims ())
+  {
+    // No checking.
+    if (m_ext < 0)
+      {
+        octave_idx_type max = -1;
+        for (octave_idx_type i = 0; i < m_len; i++)
+          if (m_data[i] > max)
+            max = m_data[i];
+
+        m_ext = max + 1;
+      }
+  }
 
-    case class_mask:
+  idx_vector::idx_vector_rep::idx_vector_rep (bool b)
+    : idx_base_rep (), m_data (nullptr), m_len (b ? 1 : 0), m_ext (0),
+      m_aowner (nullptr), m_orig_dims (m_len, m_len)
+  {
+    if (m_len != 0)
+      {
+        octave_idx_type *d = new octave_idx_type [1];
+        d[0] = 0;
+        m_data = d;
+        m_ext = 1;
+      }
+  }
+
+  idx_vector::idx_vector_rep::idx_vector_rep (const Array<bool>& bnda,
+                                              octave_idx_type nnz)
+    : idx_base_rep (), m_data (nullptr), m_len (nnz), m_ext (0),
+      m_aowner (nullptr), m_orig_dims ()
+  {
+    if (nnz < 0)
+      m_len = bnda.nnz ();
+
+    const dim_vector dv = bnda.dims ();
+
+    m_orig_dims = dv.make_nd_vector (m_len);
+
+    if (m_len != 0)
+      {
+        octave_idx_type *d = new octave_idx_type [m_len];
+
+        octave_idx_type ntot = bnda.numel ();
+
+        octave_idx_type k = 0;
+        for (octave_idx_type i = 0; i < ntot; i++)
+          if (bnda.xelem (i))
+            d[k++] = i;
+
+        m_data = d;
+
+        m_ext = d[k-1] + 1;
+      }
+  }
+
+  idx_vector::idx_vector_rep::idx_vector_rep (const Sparse<bool>& bnda)
+    : idx_base_rep (), m_data (nullptr), m_len (bnda.nnz ()), m_ext (0),
+      m_aowner (nullptr), m_orig_dims ()
+  {
+    const dim_vector dv = bnda.dims ();
+
+    m_orig_dims = dv.make_nd_vector (m_len);
+
+    if (m_len != 0)
+      {
+        octave_idx_type *d = new octave_idx_type [m_len];
+
+        octave_idx_type k = 0;
+        octave_idx_type nc = bnda.cols ();
+        octave_idx_type nr = bnda.rows ();
+
+        for (octave_idx_type j = 0; j < nc; j++)
+          for (octave_idx_type i = bnda.cidx (j); i < bnda.cidx (j+1); i++)
+            if (bnda.data (i))
+              d[k++] = j * nr + bnda.ridx (i);
+
+        m_data = d;
+
+        m_ext = d[k-1] + 1;
+      }
+  }
+
+  idx_vector::idx_vector_rep::~idx_vector_rep (void)
+  {
+    if (m_aowner)
+      delete m_aowner;
+    else
+      delete [] m_data;
+  }
+
+  octave_idx_type
+  idx_vector::idx_vector_rep::checkelem (octave_idx_type n) const
+  {
+    if (n < 0 || n >= m_len)
+      err_invalid_index (n);
+
+    return xelem (n);
+  }
+
+  idx_vector::idx_base_rep *
+  idx_vector::idx_vector_rep::sort_uniq_clone (bool uniq)
+  {
+    if (m_len == 0)
+      {
+        m_count++;
+        return this;
+      }
+
+    // This is wrapped in unique_ptr so that we don't leak on out-of-memory.
+    std::unique_ptr<idx_vector_rep> new_rep
+      (new idx_vector_rep (nullptr, m_len, m_ext, m_orig_dims, DIRECT));
+
+    if (m_ext > m_len*math::log2 (1.0 + m_len))
       {
-        idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
-        octave_idx_type m_ext = r->extent (0);
-        octave_idx_type m_len = r->length (0);
-        if (m_ext == m_len)
+        // Use standard sort via octave_sort.
+        octave_idx_type *new_data = new octave_idx_type [m_len];
+        new_rep->m_data = new_data;
+
+        std::copy_n (m_data, m_len, new_data);
+        octave_sort<octave_idx_type> lsort;
+        lsort.set_compare (ASCENDING);
+        lsort.sort (new_data, m_len);
+
+        if (uniq)
+          {
+            octave_idx_type new_len = std::unique (new_data, new_data + m_len)
+              - new_data;
+            new_rep->m_len = new_len;
+            if (new_rep->m_orig_dims.ndims () == 2 && new_rep->m_orig_dims(0) == 1)
+              new_rep->m_orig_dims = dim_vector (1, new_len);
+            else
+              new_rep->m_orig_dims = dim_vector (new_len, 1);
+          }
+      }
+    else if (uniq)
+      {
+        // Use two-pass bucket sort (only a mask array needed).
+        OCTAVE_LOCAL_BUFFER_INIT (bool, has, m_ext, false);
+        for (octave_idx_type i = 0; i < m_len; i++)
+          has[m_data[i]] = true;
+
+        octave_idx_type new_len = 0;
+        for (octave_idx_type i = 0; i < m_ext; i++)
+          new_len += has[i];
+
+        new_rep->m_len = new_len;
+        if (new_rep->m_orig_dims.ndims () == 2 && new_rep->m_orig_dims(0) == 1)
+          new_rep->m_orig_dims = dim_vector (1, new_len);
+        else
+          new_rep->m_orig_dims = dim_vector (new_len, 1);
+
+        octave_idx_type *new_data = new octave_idx_type [new_len];
+        new_rep->m_data = new_data;
+
+        for (octave_idx_type i = 0, j = 0; i < m_ext; i++)
+          if (has[i])
+            new_data[j++] = i;
+      }
+    else
+      {
+        // Use two-pass bucket sort.
+        OCTAVE_LOCAL_BUFFER_INIT (octave_idx_type, cnt, m_ext, 0);
+        for (octave_idx_type i = 0; i < m_len; i++)
+          cnt[m_data[i]]++;
+
+        octave_idx_type *new_data = new octave_idx_type [m_len];
+        new_rep->m_data = new_data;
+
+        for (octave_idx_type i = 0, j = 0; i < m_ext; i++)
           {
-            l = 0;
-            u = m_len;
-            res = true;
+            for (octave_idx_type k = 0; k < cnt[i]; k++)
+              new_data[j++] = i;
+          }
+      }
+
+    return new_rep.release ();
+  }
+
+  idx_vector::idx_base_rep *
+  idx_vector::idx_vector_rep::sort_idx (Array<octave_idx_type>& idx)
+  {
+    // This is wrapped in unique_ptr so that we don't leak on out-of-memory.
+    std::unique_ptr<idx_vector_rep> new_rep
+      (new idx_vector_rep (nullptr, m_len, m_ext, m_orig_dims, DIRECT));
+
+    if (m_ext > m_len*math::log2 (1.0 + m_len))
+      {
+        // Use standard sort via octave_sort.
+        idx.clear (m_orig_dims);
+        octave_idx_type *idx_data = idx.fortran_vec ();
+        for (octave_idx_type i = 0; i < m_len; i++)
+          idx_data[i] = i;
+
+        octave_idx_type *new_data = new octave_idx_type [m_len];
+        new_rep->m_data = new_data;
+        std::copy_n (m_data, m_len, new_data);
+
+        octave_sort<octave_idx_type> lsort;
+        lsort.set_compare (ASCENDING);
+        lsort.sort (new_data, idx_data, m_len);
+      }
+    else
+      {
+        // Use two-pass bucket sort.
+        OCTAVE_LOCAL_BUFFER_INIT (octave_idx_type, cnt, m_ext, 0);
+
+        for (octave_idx_type i = 0; i < m_len; i++)
+          cnt[m_data[i]]++;
+
+        idx.clear (m_orig_dims);
+        octave_idx_type *idx_data = idx.fortran_vec ();
+
+        octave_idx_type *new_data = new octave_idx_type [m_len];
+        new_rep->m_data = new_data;
+
+        for (octave_idx_type i = 0, k = 0; i < m_ext; i++)
+          {
+            octave_idx_type j = cnt[i];
+            cnt[i] = k;
+            k += j;
+          }
+
+        for (octave_idx_type i = 0; i < m_len; i++)
+          {
+            octave_idx_type j = m_data[i];
+            octave_idx_type k = cnt[j]++;
+            new_data[k] = j;
+            idx_data[k] = i;
           }
       }
 
-    default:
-      break;
-    }
+    return new_rep.release ();
+  }
+
+  std::ostream& idx_vector::idx_vector_rep::print (std::ostream& os) const
+  {
+    os << '[';
+
+    for (octave_idx_type i = 0; i < m_len - 1; i++)
+      os << m_data[i] << ',' << ' ';
+
+    if (m_len > 0)
+      os << m_data[m_len-1];
+
+    os << ']';
+
+    return os;
+  }
+
+  Array<double> idx_vector::idx_vector_rep::unconvert (void) const
+  {
+    Array<double> retval (m_orig_dims);
+    for (octave_idx_type i = 0; i < m_len; i++)
+      retval.xelem (i) = m_data[i] + 1;
+    return retval;
+  }
 
-  return res;
-}
+  Array<octave_idx_type> idx_vector::idx_vector_rep::as_array (void)
+  {
+    if (m_aowner)
+      return *m_aowner;
+    else
+      {
+        Array<octave_idx_type> retval (m_orig_dims);
+
+        if (m_data)
+          {
+            std::memcpy (retval.fortran_vec (), m_data, m_len*sizeof (octave_idx_type));
+            // Delete the old copy and share the m_data instead to save memory.
+            delete [] m_data;
+          }
+
+        m_data = retval.fortran_vec ();
+        m_aowner = new Array<octave_idx_type> (retval);
+
+        return retval;
+      }
+  }
+
+  idx_vector::idx_mask_rep::idx_mask_rep (bool b)
+    : idx_base_rep (), m_data (nullptr), m_len (b ? 1 : 0), m_ext (0),
+      m_lsti (-1), m_lste (-1), m_aowner (nullptr), m_orig_dims (m_len, m_len)
+  {
+    if (m_len != 0)
+      {
+        bool *d = new bool [1];
+        d[0] = true;
+        m_data = d;
+        m_ext = 1;
+      }
+  }
 
-octave_idx_type
-idx_vector::increment (void) const
-{
-  octave_idx_type retval = 0;
+  idx_vector::idx_mask_rep::idx_mask_rep (const Array<bool>& bnda,
+                                          octave_idx_type nnz)
+    : idx_base_rep (), m_data (nullptr), m_len (nnz), m_ext (bnda.numel ()),
+      m_lsti (-1), m_lste (-1), m_aowner (nullptr), m_orig_dims ()
+  {
+    if (nnz < 0)
+      m_len = bnda.nnz ();
+
+    // We truncate the extent as much as possible.  For Matlab
+    // compatibility, but maybe it's not a bad idea anyway.
+    while (m_ext > 0 && ! bnda(m_ext-1))
+      m_ext--;
+
+    const dim_vector dv = bnda.dims ();
+
+    m_orig_dims = dv.make_nd_vector (m_len);
+
+    m_aowner = new Array<bool> (bnda);
+    m_data = bnda.data ();
+  }
+
+  idx_vector::idx_mask_rep::~idx_mask_rep (void)
+  {
+    if (m_aowner)
+      delete m_aowner;
+    else
+      delete [] m_data;
+  }
 
-  switch (m_rep->idx_class ())
-    {
-    case class_colon:
-      retval = 1;
-      break;
+  octave_idx_type idx_vector::idx_mask_rep::xelem (octave_idx_type n) const
+  {
+    if (n == m_lsti + 1)
+      {
+        m_lsti = n;
+        while (! m_data[++m_lste]) ;
+      }
+    else
+      {
+        m_lsti = n++;
+        m_lste = -1;
+        while (n > 0)
+          if (m_data[++m_lste]) --n;
+      }
+    return m_lste;
+  }
 
-    case class_range:
-      retval = dynamic_cast<idx_range_rep *> (m_rep) -> get_step ();
-      break;
+  octave_idx_type idx_vector::idx_mask_rep::checkelem (octave_idx_type n) const
+  {
+    if (n < 0 || n >= m_len)
+      err_invalid_index (n);
+
+    return xelem (n);
+  }
+
+  std::ostream& idx_vector::idx_mask_rep::print (std::ostream& os) const
+  {
+    os << '[';
+
+    for (octave_idx_type i = 0; i < m_ext - 1; i++)
+      os << m_data[i] << ',' << ' ';
 
-    case class_vector:
-    case class_mask:
+    if (m_ext > 0)
+      os << m_data[m_ext-1];
+
+    os << ']';
+
+    return os;
+  }
+
+  Array<bool> idx_vector::idx_mask_rep::unconvert (void) const
+  {
+    if (m_aowner)
+      return *m_aowner;
+    else
+      {
+        Array<bool> retval (dim_vector (m_ext, 1));
+        for (octave_idx_type i = 0; i < m_ext; i++)
+          retval.xelem (i) = m_data[i];
+        return retval;
+      }
+  }
+
+  Array<octave_idx_type> idx_vector::idx_mask_rep::as_array (void)
+  {
+    if (m_aowner)
+      return m_aowner->find ().reshape (m_orig_dims);
+    else
       {
-        if (length (0) > 1)
-          retval = elem (1) - elem (0);
+        Array<bool> retval (m_orig_dims);
+        for (octave_idx_type i = 0, j = 0; i < m_ext; i++)
+          if (m_data[i])
+            retval.xelem (j++) = i;
+
+        return retval;
       }
-      break;
+  }
+
+  idx_vector::idx_base_rep *
+  idx_vector::idx_mask_rep::sort_idx (Array<octave_idx_type>& idx)
+  {
+    idx.clear (m_len, 1);
+    for (octave_idx_type i = 0; i < m_len; i++)
+      idx.xelem (i) = i;
+
+    m_count++;
+    return this;
+  }
+
+  const idx_vector idx_vector::colon (new idx_vector::idx_colon_rep ());
+
+  idx_vector::idx_vector (const Array<bool>& bnda)
+    : m_rep (nullptr)
+  {
+    // Convert only if it means saving at least half the memory.
+    static const int factor = (2 * sizeof (octave_idx_type));
+    octave_idx_type nnz = bnda.nnz ();
+    if (nnz <= bnda.numel () / factor)
+      m_rep = new idx_vector_rep (bnda, nnz);
+    else
+      m_rep = new idx_mask_rep (bnda, nnz);
+  }
 
-    default:
-      break;
-    }
+  bool idx_vector::maybe_reduce (octave_idx_type n, const idx_vector& j,
+                                 octave_idx_type nj)
+  {
+    bool reduced = false;
 
-  return retval;
-}
+    // Empty index always reduces.
+    if (m_rep->length (n) == 0)
+      {
+        *this = idx_vector ();
+        return true;
+      }
+
+    // Possibly skip singleton dims.
+    if (n == 1 && m_rep->is_colon_equiv (n))
+      {
+        *this = j;
+        return true;
+      }
+
+    if (nj == 1 && j.is_colon_equiv (nj))
+      return true;
 
-const octave_idx_type *
-idx_vector::raw (void)
-{
-  if (m_rep->idx_class () != class_vector)
-    *this = idx_vector (as_array (), extent (0));
+    switch (j.idx_class ())
+      {
+      case class_colon:
+        switch (m_rep->idx_class ())
+          {
+          case class_colon:
+            // (:,:) reduces to (:)
+            reduced = true;
+            break;
+
+          case class_scalar:
+            {
+              // (i,:) reduces to a range.
+              idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
+              octave_idx_type k = r->get_data ();
+              *this = new idx_range_rep (k, nj, n, DIRECT);
+              reduced = true;
+            }
+            break;
 
-  idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
+          case class_range:
+            {
+              // (i:k:end,:) reduces to a range if i <= k and k divides n.
+              idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
+              octave_idx_type s = r->get_start ();
+              octave_idx_type l = r->length (n);
+              octave_idx_type t = r->get_step ();
+              if (l*t == n)
+                {
+                  *this = new idx_range_rep (s, l * nj, t, DIRECT);
+                  reduced = true;
+                }
+            }
+            break;
+
+          default:
+            break;
+          }
+        break;
 
-  assert (r != nullptr);
+      case class_range:
+        switch (m_rep->idx_class ())
+          {
+          case class_colon:
+            {
+              // (:,i:j) reduces to a range (the m_step must be 1)
+              idx_range_rep *rj = dynamic_cast<idx_range_rep *> (j.m_rep);
+              if (rj->get_step () == 1)
+                {
+                  octave_idx_type sj = rj->get_start ();
+                  octave_idx_type lj = rj->length (nj);
+                  *this = new idx_range_rep (sj * n, lj * n, 1, DIRECT);
+                  reduced = true;
+                }
+            }
+            break;
 
-  return r->get_data ();
-}
+          case class_scalar:
+            {
+              // (k,i:d:j) reduces to a range.
+              idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
+              idx_range_rep *rj = dynamic_cast<idx_range_rep *> (j.m_rep);
+              octave_idx_type k = r->get_data ();
+              octave_idx_type sj = rj->get_start ();
+              octave_idx_type lj = rj->length (nj);
+              octave_idx_type tj = rj->get_step ();
+              *this = new idx_range_rep (n * sj + k, lj, n * tj, DIRECT);
+              reduced = true;
+            }
+            break;
+
+          case class_range:
+            {
+              // (i:k:end,p:q) reduces to a range if i <= k and k divides n.
+              // (ones (1, m), ones (1, n)) reduces to (ones (1, m*n))
+              idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
+              octave_idx_type s = r->get_start ();
+              octave_idx_type l = r->length (n);
+              octave_idx_type t = r->get_step ();
+              idx_range_rep *rj = dynamic_cast<idx_range_rep *> (j.m_rep);
+              octave_idx_type sj = rj->get_start ();
+              octave_idx_type lj = rj->length (nj);
+              octave_idx_type tj = rj->get_step ();
+              if ((l*t == n && tj == 1) || (t == 0 && tj == 0))
+                {
+                  *this = new idx_range_rep (s + n * sj, l * lj, t, DIRECT);
+                  reduced = true;
+                }
+            }
+            break;
+
+          default:
+            break;
+          }
+        break;
 
-void
-idx_vector::copy_data (octave_idx_type *m_data) const
-{
-  octave_idx_type m_len = m_rep->length (0);
+      case class_scalar:
+        switch (m_rep->idx_class ())
+          {
+          case class_scalar:
+            {
+              // (i,j) reduces to a single index.
+              idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
+              idx_scalar_rep *rj = dynamic_cast<idx_scalar_rep *> (j.m_rep);
+              octave_idx_type k = r->get_data () + n * rj->get_data ();
+              *this = new idx_scalar_rep (k, DIRECT);
+              reduced = true;
+            }
+            break;
+
+          case class_range:
+            {
+              // (i:d:j,k) reduces to a range.
+              idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
+              idx_scalar_rep *rj = dynamic_cast<idx_scalar_rep *> (j.m_rep);
+              octave_idx_type s = r->get_start ();
+              octave_idx_type l = r->length (nj);
+              octave_idx_type t = r->get_step ();
+              octave_idx_type k = rj->get_data ();
+              *this = new idx_range_rep (n * k + s, l, t, DIRECT);
+              reduced = true;
+            }
+            break;
 
-  switch (m_rep->idx_class ())
-    {
-    case class_colon:
-      (*current_liboctave_error_handler) ("colon not allowed");
-      break;
+          case class_colon:
+            {
+              // (:,k) reduces to a range.
+              idx_scalar_rep *rj = dynamic_cast<idx_scalar_rep *> (j.m_rep);
+              octave_idx_type k = rj->get_data ();
+              *this = new idx_range_rep (n * k, n, 1, DIRECT);
+              reduced = true;
+            }
+            break;
 
-    case class_range:
+          default:
+            break;
+          }
+        break;
+
+      default:
+        break;
+      }
+
+    return reduced;
+  }
+
+  bool idx_vector::is_cont_range (octave_idx_type n, octave_idx_type& l,
+                                  octave_idx_type& u) const
+  {
+    bool res = false;
+
+    switch (m_rep->idx_class ())
       {
-        idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
-        octave_idx_type m_start = r->get_start ();
-        octave_idx_type m_step = r->get_step ();
-        octave_idx_type i, j;
-        if (m_step == 1)
-          for (i = m_start, j = m_start + m_len; i < j; i++) *m_data++ = i;
-        else if (m_step == -1)
-          for (i = m_start, j = m_start - m_len; i > j; i--) *m_data++ = i;
-        else
-          for (i = 0, j = m_start; i < m_len; i++, j += m_step) *m_data++ = j;
+      case class_colon:
+        l = 0; u = n;
+        res = true;
+        break;
+
+      case class_range:
+        {
+          idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
+          if (r->get_step () == 1)
+            {
+              l = r->get_start ();
+              u = l + r->length (n);
+              res = true;
+            }
+        }
+        break;
+
+      case class_scalar:
+        {
+          idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
+          l = r->get_data ();
+          u = l + 1;
+          res = true;
+        }
+        break;
+
+      case class_mask:
+        {
+          idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
+          octave_idx_type m_ext = r->extent (0);
+          octave_idx_type m_len = r->length (0);
+          if (m_ext == m_len)
+            {
+              l = 0;
+              u = m_len;
+              res = true;
+            }
+        }
+
+      default:
+        break;
       }
-      break;
+
+    return res;
+  }
 
-    case class_scalar:
+  octave_idx_type idx_vector::increment (void) const
+  {
+    octave_idx_type retval = 0;
+
+    switch (m_rep->idx_class ())
       {
-        idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
-        *m_data = r->get_data ();
+      case class_colon:
+        retval = 1;
+        break;
+
+      case class_range:
+        retval = dynamic_cast<idx_range_rep *> (m_rep) -> get_step ();
+        break;
+
+      case class_vector:
+      case class_mask:
+        {
+          if (length (0) > 1)
+            retval = elem (1) - elem (0);
+        }
+        break;
+
+      default:
+        break;
       }
-      break;
+
+    return retval;
+  }
+
+  const octave_idx_type * idx_vector::raw (void)
+  {
+    if (m_rep->idx_class () != class_vector)
+      *this = idx_vector (as_array (), extent (0));
+
+    idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
 
-    case class_vector:
+    assert (r != nullptr);
+
+    return r->get_data ();
+  }
+
+  void idx_vector::copy_data (octave_idx_type *m_data) const
+  {
+    octave_idx_type m_len = m_rep->length (0);
+
+    switch (m_rep->idx_class ())
       {
-        idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
-        const octave_idx_type *rdata = r->get_data ();
-        std::copy_n (rdata, m_len, m_data);
+      case class_colon:
+        (*current_liboctave_error_handler) ("colon not allowed");
+        break;
+
+      case class_range:
+        {
+          idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
+          octave_idx_type m_start = r->get_start ();
+          octave_idx_type m_step = r->get_step ();
+          octave_idx_type i, j;
+          if (m_step == 1)
+            for (i = m_start, j = m_start + m_len; i < j; i++) *m_data++ = i;
+          else if (m_step == -1)
+            for (i = m_start, j = m_start - m_len; i > j; i--) *m_data++ = i;
+          else
+            for (i = 0, j = m_start; i < m_len; i++, j += m_step) *m_data++ = j;
+        }
+        break;
+
+      case class_scalar:
+        {
+          idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
+          *m_data = r->get_data ();
+        }
+        break;
+
+      case class_vector:
+        {
+          idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
+          const octave_idx_type *rdata = r->get_data ();
+          std::copy_n (rdata, m_len, m_data);
+        }
+        break;
+
+      case class_mask:
+        {
+          idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
+          const bool *mask = r->get_data ();
+          octave_idx_type m_ext = r->extent (0);
+          for (octave_idx_type i = 0, j = 0; i < m_ext; i++)
+            if (mask[i])
+              m_data[j++] = i;
+        }
+        break;
+
+      default:
+        assert (false);
+        break;
       }
-      break;
+  }
 
-    case class_mask:
+  idx_vector idx_vector::complement (octave_idx_type n) const
+  {
+    idx_vector retval;
+    if (extent (n) > n)
+      (*current_liboctave_error_handler)
+        ("internal error: out of range complement index requested");
+
+    if (idx_class () == class_mask)
       {
         idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
-        const bool *mask = r->get_data ();
+        octave_idx_type nz = r->length (0);
         octave_idx_type m_ext = r->extent (0);
-        for (octave_idx_type i = 0, j = 0; i < m_ext; i++)
-          if (mask[i])
-            m_data[j++] = i;
+        Array<bool> mask (dim_vector (n, 1));
+        const bool *m_data = r->get_data ();
+        bool *ndata = mask.fortran_vec ();
+        for (octave_idx_type i = 0; i < m_ext; i++)
+          ndata[i] = ! m_data[i];
+        std::fill_n (ndata + m_ext, n - m_ext, true);
+        retval = new idx_mask_rep (mask, n - nz);
       }
-      break;
-
-    default:
-      assert (false);
-      break;
-    }
-}
-
-idx_vector
-idx_vector::complement (octave_idx_type n) const
-{
-  idx_vector retval;
-  if (extent (n) > n)
-    (*current_liboctave_error_handler)
-      ("internal error: out of range complement index requested");
+    else
+      {
+        Array<bool> mask (dim_vector (n, 1), true);
+        fill (false, length (n), mask.fortran_vec ());
+        retval = idx_vector (mask);
+      }
 
-  if (idx_class () == class_mask)
-    {
-      idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
-      octave_idx_type nz = r->length (0);
-      octave_idx_type m_ext = r->extent (0);
-      Array<bool> mask (dim_vector (n, 1));
-      const bool *m_data = r->get_data ();
-      bool *ndata = mask.fortran_vec ();
-      for (octave_idx_type i = 0; i < m_ext; i++)
-        ndata[i] = ! m_data[i];
-      std::fill_n (ndata + m_ext, n - m_ext, true);
-      retval = new idx_mask_rep (mask, n - nz);
-    }
-  else
-    {
-      Array<bool> mask (dim_vector (n, 1), true);
-      fill (false, length (n), mask.fortran_vec ());
-      retval = idx_vector (mask);
-    }
+    return retval;
+  }
+
+  bool idx_vector::is_permutation (octave_idx_type n) const
+  {
+    bool retval = false;
 
-  return retval;
-}
+    if (is_colon_equiv (n))
+      retval = true;
+    else if (length(n) == n && extent(n) == n)
+      {
+        OCTAVE_LOCAL_BUFFER_INIT (bool, left, n, true);
 
-bool
-idx_vector::is_permutation (octave_idx_type n) const
-{
-  bool retval = false;
+        retval = true;
 
-  if (is_colon_equiv (n))
-    retval = true;
-  else if (length(n) == n && extent(n) == n)
-    {
-      OCTAVE_LOCAL_BUFFER_INIT (bool, left, n, true);
-
-      retval = true;
+        for (octave_idx_type i = 0, m_len = length (); i < m_len; i++)
+          {
+            octave_idx_type k = xelem (i);
+            if (left[k])
+              left[k] = false;
+            else
+              {
+                retval = false;
+                break;
+              }
+          }
+      }
 
-      for (octave_idx_type i = 0, m_len = length (); i < m_len; i++)
-        {
-          octave_idx_type k = xelem (i);
-          if (left[k])
-            left[k] = false;
-          else
-            {
-              retval = false;
-              break;
-            }
-        }
-    }
+    return retval;
+  }
 
-  return retval;
-}
+  idx_vector idx_vector::inverse_permutation (octave_idx_type n) const
+  {
+    assert (n == length (n));
+
+    idx_vector retval;
 
-idx_vector
-idx_vector::inverse_permutation (octave_idx_type n) const
-{
-  assert (n == length (n));
-
-  idx_vector retval;
-
-  switch (idx_class ())
-    {
-    case class_range:
+    switch (idx_class ())
       {
-        if (increment () == -1)
-          retval = sorted ();
-        else
-          retval = *this;
-        break;
-      }
-    case class_vector:
-      {
-        idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
-        const octave_idx_type *ri = r->get_data ();
-        Array<octave_idx_type> idx (orig_dimensions ());
-        for (octave_idx_type i = 0; i < n; i++)
-          idx.xelem (ri[i]) = i;
-        retval = new idx_vector_rep (idx, r->extent (0), DIRECT);
+      case class_range:
+        {
+          if (increment () == -1)
+            retval = sorted ();
+          else
+            retval = *this;
+          break;
+        }
+      case class_vector:
+        {
+          idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
+          const octave_idx_type *ri = r->get_data ();
+          Array<octave_idx_type> idx (orig_dimensions ());
+          for (octave_idx_type i = 0; i < n; i++)
+            idx.xelem (ri[i]) = i;
+          retval = new idx_vector_rep (idx, r->extent (0), DIRECT);
+          break;
+        }
+      default:
+        retval = *this;
         break;
       }
-    default:
-      retval = *this;
-      break;
-    }
 
-  return retval;
-}
-
-idx_vector
-idx_vector::unmask (void) const
-{
-  if (idx_class () == class_mask)
-    {
-      idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
-      const bool *m_data = r->get_data ();
-      octave_idx_type m_ext = r->extent (0);
-      octave_idx_type m_len = r->length (0);
-      octave_idx_type *idata = new octave_idx_type [m_len];
-
-      for (octave_idx_type i = 0, j = 0; i < m_ext; i++)
-        if (m_data[i])
-          idata[j++] = i;
-
-      m_ext = (m_len > 0 ? idata[m_len - 1] + 1 : 0);
-
-      return new idx_vector_rep (idata, m_len, m_ext, r->orig_dimensions (),
-                                 DIRECT);
-    }
-  else
-    return *this;
-}
+    return retval;
+  }
 
-void idx_vector::unconvert (idx_class_type& iclass,
-                            double& scalar, octave::range<double>& range,
-                            Array<double>& array, Array<bool>& mask) const
-{
-  iclass = idx_class ();
-  switch (iclass)
-    {
-    case class_colon:
-      break;
-
-    case class_range:
-      {
-        idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
-        range = r->unconvert ();
-      }
-      break;
-
-    case class_scalar:
-      {
-        idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
-        scalar = r->unconvert ();
-      }
-      break;
-
-    case class_vector:
-      {
-        idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
-        array = r->unconvert ();
-      }
-      break;
-
-    case class_mask:
+  idx_vector idx_vector::unmask (void) const
+  {
+    if (idx_class () == class_mask)
       {
         idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
-        mask = r->unconvert ();
-      }
-      break;
+        const bool *m_data = r->get_data ();
+        octave_idx_type m_ext = r->extent (0);
+        octave_idx_type m_len = r->length (0);
+        octave_idx_type *idata = new octave_idx_type [m_len];
+
+        for (octave_idx_type i = 0, j = 0; i < m_ext; i++)
+          if (m_data[i])
+            idata[j++] = i;
 
-    default:
-      assert (false);
-      break;
-    }
-}
+        m_ext = (m_len > 0 ? idata[m_len - 1] + 1 : 0);
+
+        return new idx_vector_rep (idata, m_len, m_ext, r->orig_dimensions (),
+                                   DIRECT);
+      }
+    else
+      return *this;
+  }
 
-Array<octave_idx_type>
-idx_vector::as_array (void) const
-{
-  return m_rep->as_array ();
-}
+  void idx_vector::unconvert (idx_class_type& iclass,
+                              double& scalar, range<double>& range,
+                              Array<double>& array, Array<bool>& mask) const
+  {
+    iclass = idx_class ();
+    switch (iclass)
+      {
+      case class_colon:
+        break;
 
-bool
-idx_vector::isvector (void) const
-{
-  return idx_class () != class_vector || orig_dimensions ().isvector ();
-}
+      case class_range:
+        {
+          idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
+          range = r->unconvert ();
+        }
+        break;
+
+      case class_scalar:
+        {
+          idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
+          scalar = r->unconvert ();
+        }
+        break;
+
+      case class_vector:
+        {
+          idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
+          array = r->unconvert ();
+        }
+        break;
 
-octave_idx_type
-idx_vector::freeze (octave_idx_type z_len, const char *, bool resize_ok)
-{
-  if (! resize_ok && extent (z_len) > z_len)
-    (*current_liboctave_error_handler)
-      ("invalid matrix index = %" OCTAVE_IDX_TYPE_FORMAT, extent (z_len));
+      case class_mask:
+        {
+          idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
+          mask = r->unconvert ();
+        }
+        break;
 
-  return length (z_len);
-}
+      default:
+        assert (false);
+        break;
+      }
+  }
+
+  Array<octave_idx_type> idx_vector::as_array (void) const
+  {
+    return m_rep->as_array ();
+  }
+
+  bool idx_vector::isvector (void) const
+  {
+    return idx_class () != class_vector || orig_dimensions ().isvector ();
+  }
 
-octave_idx_type
-idx_vector::ones_count () const
-{
-  octave_idx_type n = 0;
+  octave_idx_type
+  idx_vector::freeze (octave_idx_type z_len, const char *, bool resize_ok)
+  {
+    if (! resize_ok && extent (z_len) > z_len)
+      (*current_liboctave_error_handler)
+        ("invalid matrix index = %" OCTAVE_IDX_TYPE_FORMAT, extent (z_len));
+
+    return length (z_len);
+  }
+
+  octave_idx_type idx_vector::ones_count () const
+  {
+    octave_idx_type n = 0;
 
-  if (is_colon ())
-    n = 1;
-  else
-    {
-      for (octave_idx_type i = 0; i < length (1); i++)
-        if (xelem (i) == 0)
-          n++;
-    }
+    if (is_colon ())
+      n = 1;
+    else
+      {
+        for (octave_idx_type i = 0; i < length (1); i++)
+          if (xelem (i) == 0)
+            n++;
+      }
 
-  return n;
-}
+    return n;
+  }
 
-// Instantiate the octave_int constructors we want.
+  // Instantiate the octave_int constructors we want.
 #define INSTANTIATE_SCALAR_VECTOR_REP_CONST(T)                          \
   template OCTAVE_API idx_vector::idx_scalar_rep::idx_scalar_rep (T);   \
   template OCTAVE_API idx_vector::idx_vector_rep::idx_vector_rep (const Array<T>&);
 
-INSTANTIATE_SCALAR_VECTOR_REP_CONST (float)
-INSTANTIATE_SCALAR_VECTOR_REP_CONST (double)
-INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_int8)
-INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_int16)
-INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_int32)
-INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_int64)
-INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_uint8)
-INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_uint16)
-INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_uint32)
-INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_uint64)
+  INSTANTIATE_SCALAR_VECTOR_REP_CONST (float)
+  INSTANTIATE_SCALAR_VECTOR_REP_CONST (double)
+  INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_int8)
+  INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_int16)
+  INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_int32)
+  INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_int64)
+  INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_uint8)
+  INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_uint16)
+  INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_uint32)
+  INSTANTIATE_SCALAR_VECTOR_REP_CONST (octave_uint64)
+}
 
 /*
 
--- a/liboctave/array/idx-vector.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/array/idx-vector.h	Wed Apr 28 13:46:02 2021 -0400
@@ -45,985 +45,990 @@
 namespace octave
 {
   template <typename T> class range;
-}
-
-// Design rationale:
-//
-// idx_vector is a reference-counting, polymorphic pointer, that can
-// contain 4 types of index objects: a magic colon, a range, a scalar,
-// or an index vector.
-//
-// Polymorphic methods for single element access are provided, as well
-// as templates implementing "early dispatch", i.e., hoisting the checks
-// for index type out of loops.
-
-class
-OCTAVE_API
-idx_vector
-{
-public:
-
-  enum idx_class_type
-  {
-    class_invalid = -1,
-    class_colon = 0,
-    class_range,
-    class_scalar,
-    class_vector,
-    class_mask
-  };
-
-  template <typename T, typename D> friend class std::unique_ptr;
-
-private:
-
-  class OCTAVE_API idx_base_rep
-  {
-  public:
-
-    idx_base_rep (void) : m_count (1) { }
-
-    // No copying!
-
-    idx_base_rep (const idx_base_rep&) = delete;
-
-    idx_base_rep& operator = (const idx_base_rep&) = delete;
-
-    virtual ~idx_base_rep (void) = default;
-
-    // Non-range-checking element query.
-    virtual octave_idx_type xelem (octave_idx_type i) const = 0;
-
-    // Range-checking element query.
-    virtual octave_idx_type checkelem (octave_idx_type i) const = 0;
-
-    // Length of the index vector.
-    virtual octave_idx_type length (octave_idx_type n) const = 0;
-
-    // The maximum index + 1.  The actual dimension is passed in.
-    virtual octave_idx_type extent (octave_idx_type n) const = 0;
-
-    // Index class.
-    virtual idx_class_type idx_class (void) const { return class_invalid; }
-
-    // Sorts, maybe uniqifies, and returns a clone object pointer.
-    virtual idx_base_rep * sort_uniq_clone (bool uniq = false) = 0;
-    // Sorts, and returns a sorting permutation (aka Array::sort).
-    virtual idx_base_rep * sort_idx (Array<octave_idx_type>&) = 0;
-
-    // Checks whether the index is colon or a range equivalent to colon.
-    virtual bool is_colon_equiv (octave_idx_type) const { return false; }
-
-    // The original dimensions of object (used when subscribing by matrices).
-    virtual dim_vector orig_dimensions (void) const { return dim_vector (); }
-
-    // i/o
-    virtual std::ostream& print (std::ostream& os) const = 0;
-
-    virtual Array<octave_idx_type> as_array (void);
-
-    octave::refcount<octave_idx_type> m_count;
-  };
-
-  // The magic colon index.
-  class OCTAVE_API idx_colon_rep : public idx_base_rep
-  {
-  public:
-
-    idx_colon_rep (void) = default;
-
-    idx_colon_rep (char c);
-
-    // No copying!
 
-    idx_colon_rep (const idx_colon_rep& idx) = delete;
-
-    idx_colon_rep& operator = (const idx_colon_rep& idx) = delete;
-
-    octave_idx_type xelem (octave_idx_type i) const { return i; }
-
-    octave_idx_type checkelem (octave_idx_type i) const;
-
-    octave_idx_type length (octave_idx_type n) const { return n; }
-
-    octave_idx_type extent (octave_idx_type n) const { return n; }
-
-    idx_class_type idx_class (void) const { return class_colon; }
-
-    idx_base_rep * sort_uniq_clone (bool = false)
-    { m_count++; return this; }
-
-    OCTAVE_NORETURN idx_base_rep * sort_idx (Array<octave_idx_type>&);
-
-    bool is_colon_equiv (octave_idx_type) const { return true; }
-
-    std::ostream& print (std::ostream& os) const;
-  };
-
-  // To distinguish the "direct" constructors that blindly trust the data.
-  enum direct { DIRECT };
-
-  // The integer range index.
-  class OCTAVE_API idx_range_rep : public idx_base_rep
-  {
-  public:
-
-    idx_range_rep (void) = delete;
-
-    idx_range_rep (octave_idx_type start, octave_idx_type len,
-                   octave_idx_type step, direct)
-      : idx_base_rep (), m_start (start), m_len (len), m_step (step) { }
-
-    // Zero-based constructor.
-    idx_range_rep (octave_idx_type start, octave_idx_type limit,
-                   octave_idx_type step);
-
-    idx_range_rep (const octave::range<double>&);
-
-    // No copying!
+  // Design rationale:
+  //
+  // idx_vector is a reference-counting, polymorphic pointer, that can
+  // contain 4 types of index objects: a magic colon, a range, a scalar,
+  // or an index vector.
+  //
+  // Polymorphic methods for single element access are provided, as well
+  // as templates implementing "early dispatch", i.e., hoisting the checks
+  // for index type out of loops.
 
-    idx_range_rep (const idx_range_rep& idx) = delete;
-
-    idx_range_rep& operator = (const idx_range_rep& idx) = delete;
-
-    octave_idx_type xelem (octave_idx_type i) const
-    { return m_start + i * m_step; }
-
-    octave_idx_type checkelem (octave_idx_type i) const;
-
-    octave_idx_type length (octave_idx_type) const { return m_len; }
-
-    octave_idx_type extent (octave_idx_type n) const
-    {
-      return m_len ? std::max (n, m_start + 1 + (m_step < 0 ? 0 : m_step * (m_len - 1))) : n;
-    }
-
-    idx_class_type idx_class (void) const { return class_range; }
-
-    idx_base_rep * sort_uniq_clone (bool uniq = false);
-
-    idx_base_rep * sort_idx (Array<octave_idx_type>&);
-
-    bool is_colon_equiv (octave_idx_type n) const
-    { return m_start == 0 && m_step == 1 && m_len == n; }
-
-    dim_vector orig_dimensions (void) const
-    { return dim_vector (1, m_len); }
-
-    octave_idx_type get_start (void) const { return m_start; }
-
-    octave_idx_type get_step (void) const { return m_step; }
-
-    std::ostream& print (std::ostream& os) const;
-
-    octave::range<double> unconvert (void) const;
-
-    Array<octave_idx_type> as_array (void);
-
-  private:
-
-    octave_idx_type m_start, m_len, m_step;
-  };
-
-  // The integer scalar index.
-  class OCTAVE_API idx_scalar_rep : public idx_base_rep
+  class
+  OCTAVE_API
+  idx_vector
   {
   public:
 
-    idx_scalar_rep (void) = delete;
+    enum idx_class_type
+    {
+      class_invalid = -1,
+      class_colon = 0,
+      class_range,
+      class_scalar,
+      class_vector,
+      class_mask
+    };
 
-    idx_scalar_rep (octave_idx_type i, direct) : idx_base_rep (), m_data (i) { }
-
-    // No copying!
+    template <typename T, typename D> friend class std::unique_ptr;
 
-    idx_scalar_rep (const idx_scalar_rep& idx) = delete;
+    private:
+
+    class OCTAVE_API idx_base_rep
+    {
+    public:
 
-    idx_scalar_rep& operator = (const idx_scalar_rep& idx) = delete;
+      idx_base_rep (void) : m_count (1) { }
 
-    // Zero-based constructor.
-    idx_scalar_rep (octave_idx_type i);
+      // No copying!
+
+      idx_base_rep (const idx_base_rep&) = delete;
 
-    template <typename T>
-    idx_scalar_rep (T x);
+      idx_base_rep& operator = (const idx_base_rep&) = delete;
+
+      virtual ~idx_base_rep (void) = default;
 
-    octave_idx_type xelem (octave_idx_type) const { return m_data; }
+      // Non-range-checking element query.
+      virtual octave_idx_type xelem (octave_idx_type i) const = 0;
 
-    octave_idx_type checkelem (octave_idx_type i) const;
+      // Range-checking element query.
+      virtual octave_idx_type checkelem (octave_idx_type i) const = 0;
 
-    octave_idx_type length (octave_idx_type) const { return 1; }
+      // Length of the index vector.
+      virtual octave_idx_type length (octave_idx_type n) const = 0;
+
+      // The maximum index + 1.  The actual dimension is passed in.
+      virtual octave_idx_type extent (octave_idx_type n) const = 0;
 
-    octave_idx_type extent (octave_idx_type n) const
-    { return std::max (n, m_data + 1); }
+      // Index class.
+      virtual idx_class_type idx_class (void) const { return class_invalid; }
 
-    idx_class_type idx_class (void) const { return class_scalar; }
+      // Sorts, maybe uniqifies, and returns a clone object pointer.
+      virtual idx_base_rep * sort_uniq_clone (bool uniq = false) = 0;
+      // Sorts, and returns a sorting permutation (aka Array::sort).
+      virtual idx_base_rep * sort_idx (Array<octave_idx_type>&) = 0;
 
-    idx_base_rep * sort_uniq_clone (bool = false)
-    { m_count++; return this; }
+      // Checks whether the index is colon or a range equivalent to colon.
+      virtual bool is_colon_equiv (octave_idx_type) const { return false; }
 
-    idx_base_rep * sort_idx (Array<octave_idx_type>&);
+      // The original dimensions of object (used when subscribing by matrices).
+      virtual dim_vector orig_dimensions (void) const { return dim_vector (); }
+
+      // i/o
+      virtual std::ostream& print (std::ostream& os) const = 0;
+
+      virtual Array<octave_idx_type> as_array (void);
 
-    bool is_colon_equiv (octave_idx_type n) const
-    { return n == 1 && m_data == 0; }
+      refcount<octave_idx_type> m_count;
+    };
 
-    dim_vector orig_dimensions (void) const { return dim_vector (1, 1); }
+    // The magic colon index.
+    class OCTAVE_API idx_colon_rep : public idx_base_rep
+    {
+    public:
 
-    octave_idx_type get_data (void) const { return m_data; }
+      idx_colon_rep (void) = default;
 
-    std::ostream& print (std::ostream& os) const;
+      idx_colon_rep (char c);
 
-    double unconvert (void) const;
+      // No copying!
+
+      idx_colon_rep (const idx_colon_rep& idx) = delete;
+
+      idx_colon_rep& operator = (const idx_colon_rep& idx) = delete;
 
-    Array<octave_idx_type> as_array (void);
+      octave_idx_type xelem (octave_idx_type i) const { return i; }
 
-  private:
+      octave_idx_type checkelem (octave_idx_type i) const;
+
+      octave_idx_type length (octave_idx_type n) const { return n; }
 
-    octave_idx_type m_data;
-  };
+      octave_idx_type extent (octave_idx_type n) const { return n; }
+
+      idx_class_type idx_class (void) const { return class_colon; }
+
+      idx_base_rep * sort_uniq_clone (bool = false)
+      { m_count++; return this; }
 
-  // The integer vector index.
-  class OCTAVE_API idx_vector_rep : public idx_base_rep
-  {
-  public:
+      OCTAVE_NORETURN idx_base_rep * sort_idx (Array<octave_idx_type>&);
+
+      bool is_colon_equiv (octave_idx_type) const { return true; }
+
+      std::ostream& print (std::ostream& os) const;
+    };
 
-    idx_vector_rep (void)
-      : m_data (nullptr), m_len (0), m_ext (0), m_aowner (nullptr), m_orig_dims () { }
+    // To distinguish the "direct" constructors that blindly trust the data.
+    enum direct { DIRECT };
+
+    // The integer range index.
+    class OCTAVE_API idx_range_rep : public idx_base_rep
+    {
+    public:
+
+      idx_range_rep (void) = delete;
 
-    // Direct constructor.
-    idx_vector_rep (octave_idx_type *data, octave_idx_type len,
-                    octave_idx_type ext, const dim_vector& od, direct)
-      : idx_base_rep (), m_data (data), m_len (len), m_ext (ext),
-        m_aowner (nullptr), m_orig_dims (od)
-    { }
+      idx_range_rep (octave_idx_type start, octave_idx_type len,
+                     octave_idx_type step, direct)
+        : idx_base_rep (), m_start (start), m_len (len), m_step (step) { }
 
-    // Zero-based constructor.
-    idx_vector_rep (const Array<octave_idx_type>& inda);
+      // Zero-based constructor.
+      idx_range_rep (octave_idx_type start, octave_idx_type limit,
+                     octave_idx_type step);
+
+      idx_range_rep (const range<double>&);
+
+      // No copying!
 
-    idx_vector_rep (const Array<octave_idx_type>& inda,
-                    octave_idx_type ext, direct);
+      idx_range_rep (const idx_range_rep& idx) = delete;
+
+      idx_range_rep& operator = (const idx_range_rep& idx) = delete;
 
-    template <typename T>
-    idx_vector_rep (const Array<T>&);
+      octave_idx_type xelem (octave_idx_type i) const
+      { return m_start + i * m_step; }
+
+      octave_idx_type checkelem (octave_idx_type i) const;
+
+      octave_idx_type length (octave_idx_type) const { return m_len; }
 
-    idx_vector_rep (bool);
+      octave_idx_type extent (octave_idx_type n) const
+      {
+        return m_len ? std::max (n, m_start + 1 + (m_step < 0 ? 0 : m_step * (m_len - 1))) : n;
+      }
 
-    idx_vector_rep (const Array<bool>&, octave_idx_type = -1);
+      idx_class_type idx_class (void) const { return class_range; }
 
-    idx_vector_rep (const Sparse<bool>&);
+      idx_base_rep * sort_uniq_clone (bool uniq = false);
 
-    // No copying!
+      idx_base_rep * sort_idx (Array<octave_idx_type>&);
+
+      bool is_colon_equiv (octave_idx_type n) const
+      { return m_start == 0 && m_step == 1 && m_len == n; }
 
-    idx_vector_rep (const idx_vector_rep& idx) = delete;
+      dim_vector orig_dimensions (void) const
+      { return dim_vector (1, m_len); }
+
+      octave_idx_type get_start (void) const { return m_start; }
 
-    idx_vector_rep& operator = (const idx_vector_rep& idx) = delete;
+      octave_idx_type get_step (void) const { return m_step; }
 
-    ~idx_vector_rep (void);
+      std::ostream& print (std::ostream& os) const;
+
+      range<double> unconvert (void) const;
 
-    octave_idx_type xelem (octave_idx_type i) const { return m_data[i]; }
+      Array<octave_idx_type> as_array (void);
+
+    private:
+
+      octave_idx_type m_start, m_len, m_step;
+    };
 
-    octave_idx_type checkelem (octave_idx_type i) const;
+    // The integer scalar index.
+    class OCTAVE_API idx_scalar_rep : public idx_base_rep
+    {
+    public:
 
-    octave_idx_type length (octave_idx_type) const { return m_len; }
+      idx_scalar_rep (void) = delete;
 
-    octave_idx_type extent (octave_idx_type n) const
-    { return std::max (n, m_ext); }
+      idx_scalar_rep (octave_idx_type i, direct) : idx_base_rep (), m_data (i) { }
+
+      // No copying!
 
-    idx_class_type idx_class (void) const { return class_vector; }
+      idx_scalar_rep (const idx_scalar_rep& idx) = delete;
 
-    idx_base_rep * sort_uniq_clone (bool uniq = false);
+      idx_scalar_rep& operator = (const idx_scalar_rep& idx) = delete;
+
+      // Zero-based constructor.
+      idx_scalar_rep (octave_idx_type i);
 
-    idx_base_rep * sort_idx (Array<octave_idx_type>&);
+      template <typename T>
+        idx_scalar_rep (T x);
 
-    dim_vector orig_dimensions (void) const { return m_orig_dims; }
+      octave_idx_type xelem (octave_idx_type) const { return m_data; }
+
+      octave_idx_type checkelem (octave_idx_type i) const;
 
-    const octave_idx_type * get_data (void) const { return m_data; }
+      octave_idx_type length (octave_idx_type) const { return 1; }
 
-    std::ostream& print (std::ostream& os) const;
+      octave_idx_type extent (octave_idx_type n) const
+      { return std::max (n, m_data + 1); }
 
-    Array<double> unconvert (void) const;
+      idx_class_type idx_class (void) const { return class_scalar; }
 
-    Array<octave_idx_type> as_array (void);
+      idx_base_rep * sort_uniq_clone (bool = false)
+      { m_count++; return this; }
+
+      idx_base_rep * sort_idx (Array<octave_idx_type>&);
 
-  private:
+      bool is_colon_equiv (octave_idx_type n) const
+      { return n == 1 && m_data == 0; }
+
+      dim_vector orig_dimensions (void) const { return dim_vector (1, 1); }
 
-    const octave_idx_type *m_data;
-    octave_idx_type m_len;
-    octave_idx_type m_ext;
+      octave_idx_type get_data (void) const { return m_data; }
+
+      std::ostream& print (std::ostream& os) const;
+
+      double unconvert (void) const;
+
+      Array<octave_idx_type> as_array (void);
+
+    private:
 
-    // This is a trick to allow user-given zero-based arrays to be used
-    // as indices without copying.  If the following pointer is nonzero,
-    // we do not own the data, but rather have an Array<octave_idx_type>
-    // object that provides us the data.  Note that we need a pointer
-    // because we deferred the Array<T> declaration and we do not want
-    // it yet to be defined.
+      octave_idx_type m_data;
+    };
 
-    Array<octave_idx_type> *m_aowner;
+    // The integer vector index.
+    class OCTAVE_API idx_vector_rep : public idx_base_rep
+    {
+    public:
+
+      idx_vector_rep (void)
+        : m_data (nullptr), m_len (0), m_ext (0), m_aowner (nullptr), m_orig_dims () { }
 
-    dim_vector m_orig_dims;
-  };
+      // Direct constructor.
+      idx_vector_rep (octave_idx_type *data, octave_idx_type len,
+                      octave_idx_type ext, const dim_vector& od, direct)
+        : idx_base_rep (), m_data (data), m_len (len), m_ext (ext),
+        m_aowner (nullptr), m_orig_dims (od)
+        { }
 
-  // The logical mask index.
-  class OCTAVE_API idx_mask_rep : public idx_base_rep
-  {
-  public:
+      // Zero-based constructor.
+      idx_vector_rep (const Array<octave_idx_type>& inda);
 
-    idx_mask_rep (void) = delete;
+      idx_vector_rep (const Array<octave_idx_type>& inda,
+                      octave_idx_type ext, direct);
 
-    // Direct constructor.
-    idx_mask_rep (bool *data, octave_idx_type len,
-                  octave_idx_type ext, const dim_vector& od, direct)
-      : idx_base_rep (), m_data (data), m_len (len), m_ext (ext),
-        m_lsti (-1), m_lste (-1), m_aowner (nullptr), m_orig_dims (od)
-    { }
+      template <typename T>
+        idx_vector_rep (const Array<T>&);
+
+      idx_vector_rep (bool);
+
+      idx_vector_rep (const Array<bool>&, octave_idx_type = -1);
+
+      idx_vector_rep (const Sparse<bool>&);
+
+      // No copying!
 
-    idx_mask_rep (bool);
+      idx_vector_rep (const idx_vector_rep& idx) = delete;
+
+      idx_vector_rep& operator = (const idx_vector_rep& idx) = delete;
+
+      ~idx_vector_rep (void);
 
-    idx_mask_rep (const Array<bool>&, octave_idx_type = -1);
+      octave_idx_type xelem (octave_idx_type i) const { return m_data[i]; }
 
-    // No copying!
+      octave_idx_type checkelem (octave_idx_type i) const;
+
+      octave_idx_type length (octave_idx_type) const { return m_len; }
 
-    idx_mask_rep (const idx_mask_rep& idx) = delete;
+      octave_idx_type extent (octave_idx_type n) const
+      { return std::max (n, m_ext); }
+
+      idx_class_type idx_class (void) const { return class_vector; }
 
-    idx_mask_rep& operator = (const idx_mask_rep& idx) = delete;
+      idx_base_rep * sort_uniq_clone (bool uniq = false);
 
-    ~idx_mask_rep (void);
+      idx_base_rep * sort_idx (Array<octave_idx_type>&);
+
+      dim_vector orig_dimensions (void) const { return m_orig_dims; }
 
-    octave_idx_type xelem (octave_idx_type i) const;
+      const octave_idx_type * get_data (void) const { return m_data; }
 
-    octave_idx_type checkelem (octave_idx_type i) const;
+      std::ostream& print (std::ostream& os) const;
+
+      Array<double> unconvert (void) const;
 
-    octave_idx_type length (octave_idx_type) const { return m_len; }
+      Array<octave_idx_type> as_array (void);
+
+    private:
 
-    octave_idx_type extent (octave_idx_type n) const
-    { return std::max (n, m_ext); }
+      const octave_idx_type *m_data;
+      octave_idx_type m_len;
+      octave_idx_type m_ext;
 
-    idx_class_type idx_class (void) const { return class_mask; }
+      // This is a trick to allow user-given zero-based arrays to be used
+      // as indices without copying.  If the following pointer is nonzero,
+      // we do not own the data, but rather have an Array<octave_idx_type>
+      // object that provides us the data.  Note that we need a pointer
+      // because we deferred the Array<T> declaration and we do not want
+      // it yet to be defined.
 
-    idx_base_rep * sort_uniq_clone (bool = false)
-    { m_count++; return this; }
+      Array<octave_idx_type> *m_aowner;
+
+      dim_vector m_orig_dims;
+    };
 
-    idx_base_rep * sort_idx (Array<octave_idx_type>&);
+    // The logical mask index.
+    class OCTAVE_API idx_mask_rep : public idx_base_rep
+    {
+    public:
+
+      idx_mask_rep (void) = delete;
 
-    dim_vector orig_dimensions (void) const { return m_orig_dims; }
-
-    bool is_colon_equiv (octave_idx_type n) const
-    { return m_len == n && m_ext == n; }
+      // Direct constructor.
+      idx_mask_rep (bool *data, octave_idx_type len,
+                    octave_idx_type ext, const dim_vector& od, direct)
+        : idx_base_rep (), m_data (data), m_len (len), m_ext (ext),
+        m_lsti (-1), m_lste (-1), m_aowner (nullptr), m_orig_dims (od)
+        { }
 
-    const bool * get_data (void) const { return m_data; }
+      idx_mask_rep (bool);
+
+      idx_mask_rep (const Array<bool>&, octave_idx_type = -1);
+
+      // No copying!
 
-    std::ostream& print (std::ostream& os) const;
+      idx_mask_rep (const idx_mask_rep& idx) = delete;
 
-    Array<bool> unconvert (void) const;
+      idx_mask_rep& operator = (const idx_mask_rep& idx) = delete;
+
+      ~idx_mask_rep (void);
 
-    Array<octave_idx_type> as_array (void);
+      octave_idx_type xelem (octave_idx_type i) const;
 
-  private:
+      octave_idx_type checkelem (octave_idx_type i) const;
+
+      octave_idx_type length (octave_idx_type) const { return m_len; }
 
-    const bool *m_data;
-    octave_idx_type m_len;
-    octave_idx_type m_ext;
+      octave_idx_type extent (octave_idx_type n) const
+      { return std::max (n, m_ext); }
+
+      idx_class_type idx_class (void) const { return class_mask; }
+
+      idx_base_rep * sort_uniq_clone (bool = false)
+      { m_count++; return this; }
 
-    // FIXME: I'm not sure if this is a good design.  Maybe it would be
-    // better to employ some sort of generalized iteration scheme.
-    mutable octave_idx_type m_lsti;
-    mutable octave_idx_type m_lste;
+      idx_base_rep * sort_idx (Array<octave_idx_type>&);
+
+      dim_vector orig_dimensions (void) const { return m_orig_dims; }
+
+      bool is_colon_equiv (octave_idx_type n) const
+      { return m_len == n && m_ext == n; }
+
+      const bool * get_data (void) const { return m_data; }
+
+      std::ostream& print (std::ostream& os) const;
+
+      Array<bool> unconvert (void) const;
 
-    // This is a trick to allow user-given mask arrays to be used as
-    // indices without copying.  If the following pointer is nonzero, we
-    // do not own the data, but rather have an Array<bool> object that
-    // provides us the data.  Note that we need a pointer because we
-    // deferred the Array<T> declaration and we do not want it yet to be
-    // defined.
+      Array<octave_idx_type> as_array (void);
+
+    private:
 
-    Array<bool> *m_aowner;
+      const bool *m_data;
+      octave_idx_type m_len;
+      octave_idx_type m_ext;
+
+      // FIXME: I'm not sure if this is a good design.  Maybe it would be
+      // better to employ some sort of generalized iteration scheme.
+      mutable octave_idx_type m_lsti;
+      mutable octave_idx_type m_lste;
 
-    dim_vector m_orig_dims;
-  };
+      // This is a trick to allow user-given mask arrays to be used as
+      // indices without copying.  If the following pointer is nonzero, we
+      // do not own the data, but rather have an Array<bool> object that
+      // provides us the data.  Note that we need a pointer because we
+      // deferred the Array<T> declaration and we do not want it yet to be
+      // defined.
 
-  idx_vector (idx_base_rep *r) : m_rep (r) { }
+      Array<bool> *m_aowner;
+
+      dim_vector m_orig_dims;
+    };
 
-  // The shared empty vector representation (for fast default
-  // constructor).
-  static idx_vector_rep *nil_rep (void);
+    idx_vector (idx_base_rep *r) : m_rep (r) { }
 
-public:
+    // The shared empty vector representation (for fast default
+    // constructor).
+    static idx_vector_rep *nil_rep (void);
 
-  // Fast empty constructor.
-  idx_vector (void) : m_rep (nil_rep ()) { m_rep->m_count++; }
+    public:
 
-  // Zero-based constructors (for use from C++).
-  idx_vector (octave_idx_type i) : m_rep (new idx_scalar_rep (i)) { }
+    // Fast empty constructor.
+    idx_vector (void) : m_rep (nil_rep ()) { m_rep->m_count++; }
+
+    // Zero-based constructors (for use from C++).
+    idx_vector (octave_idx_type i) : m_rep (new idx_scalar_rep (i)) { }
 
 #if OCTAVE_SIZEOF_F77_INT_TYPE != OCTAVE_SIZEOF_IDX_TYPE
-  idx_vector (octave_f77_int_type i)
+    idx_vector (octave_f77_int_type i)
     : m_rep (new idx_scalar_rep (static_cast<octave_idx_type> (i))) { }
 #endif
 
-  idx_vector (octave_idx_type start, octave_idx_type limit,
-              octave_idx_type step = 1)
+    idx_vector (octave_idx_type start, octave_idx_type limit,
+                octave_idx_type step = 1)
     : m_rep (new idx_range_rep (start, limit, step)) { }
 
-  static idx_vector
-  make_range (octave_idx_type start, octave_idx_type step,
-              octave_idx_type len)
-  {
-    return idx_vector (new idx_range_rep (start, len, step, DIRECT));
-  }
+    static idx_vector
+    make_range (octave_idx_type start, octave_idx_type step,
+                octave_idx_type len)
+    {
+      return idx_vector (new idx_range_rep (start, len, step, DIRECT));
+    }
 
-  idx_vector (const Array<octave_idx_type>& inda)
+    idx_vector (const Array<octave_idx_type>& inda)
     : m_rep (new idx_vector_rep (inda)) { }
 
-  // Directly pass extent, no checking.
-  idx_vector (const Array<octave_idx_type>& inda, octave_idx_type ext)
+    // Directly pass extent, no checking.
+    idx_vector (const Array<octave_idx_type>& inda, octave_idx_type ext)
     : m_rep (new idx_vector_rep (inda, ext, DIRECT)) { }
 
-  // Colon is best constructed by simply copying (or referencing) this member.
-  static const idx_vector colon;
+    // Colon is best constructed by simply copying (or referencing) this member.
+    static const idx_vector colon;
 
-  // or passing ':' here
-  idx_vector (char c) : m_rep (new idx_colon_rep (c)) { }
+    // or passing ':' here
+    idx_vector (char c) : m_rep (new idx_colon_rep (c)) { }
 
-  // Conversion constructors (used by interpreter).
+    // Conversion constructors (used by interpreter).
 
-  template <typename T>
-  idx_vector (octave_int<T> x) : m_rep (new idx_scalar_rep (x)) { }
+    template <typename T>
+    idx_vector (octave_int<T> x) : m_rep (new idx_scalar_rep (x)) { }
 
-  idx_vector (double x) : m_rep (new idx_scalar_rep (x)) { }
+    idx_vector (double x) : m_rep (new idx_scalar_rep (x)) { }
 
-  idx_vector (float x) : m_rep (new idx_scalar_rep (x)) { }
+    idx_vector (float x) : m_rep (new idx_scalar_rep (x)) { }
 
-  // A scalar bool does not necessarily map to scalar index.
-  idx_vector (bool x) : m_rep (new idx_mask_rep (x)) { }
+    // A scalar bool does not necessarily map to scalar index.
+    idx_vector (bool x) : m_rep (new idx_mask_rep (x)) { }
 
-  template <typename T>
-  idx_vector (const Array<octave_int<T>>& nda)
+    template <typename T>
+    idx_vector (const Array<octave_int<T>>& nda)
     : m_rep (new idx_vector_rep (nda)) { }
 
-  idx_vector (const Array<double>& nda) : m_rep (new idx_vector_rep (nda)) { }
+    idx_vector (const Array<double>& nda) : m_rep (new idx_vector_rep (nda)) { }
 
-  idx_vector (const Array<float>& nda) : m_rep (new idx_vector_rep (nda)) { }
+    idx_vector (const Array<float>& nda) : m_rep (new idx_vector_rep (nda)) { }
 
-  idx_vector (const Array<bool>& nda);
+    idx_vector (const Array<bool>& nda);
 
-  idx_vector (const octave::range<double>& r) : m_rep (new idx_range_rep (r)) { }
+    idx_vector (const range<double>& r) : m_rep (new idx_range_rep (r)) { }
 
-  idx_vector (const Sparse<bool>& nda) : m_rep (new idx_vector_rep (nda)) { }
+    idx_vector (const Sparse<bool>& nda) : m_rep (new idx_vector_rep (nda)) { }
 
-  idx_vector (const idx_vector& a) : m_rep (a.m_rep) { m_rep->m_count++; }
+    idx_vector (const idx_vector& a) : m_rep (a.m_rep) { m_rep->m_count++; }
 
-  ~idx_vector (void)
-  {
-    if (--m_rep->m_count == 0 && m_rep != nil_rep ())
-      delete m_rep;
-  }
+    ~idx_vector (void)
+    {
+      if (--m_rep->m_count == 0 && m_rep != nil_rep ())
+        delete m_rep;
+    }
 
-  idx_vector& operator = (const idx_vector& a)
-  {
-    if (this != &a)
-      {
-        if (--m_rep->m_count == 0 && m_rep != nil_rep ())
-          delete m_rep;
-
-        m_rep = a.m_rep;
-        m_rep->m_count++;
-      }
-    return *this;
-  }
+    idx_vector& operator = (const idx_vector& a)
+    {
+      if (this != &a)
+        {
+          if (--m_rep->m_count == 0 && m_rep != nil_rep ())
+            delete m_rep;
 
-  idx_class_type idx_class (void) const { return m_rep->idx_class (); }
-
-  octave_idx_type length (octave_idx_type n = 0) const
-  { return m_rep->length (n); }
+          m_rep = a.m_rep;
+          m_rep->m_count++;
+        }
+      return *this;
+    }
 
-  octave_idx_type extent (octave_idx_type n) const
-  { return m_rep->extent (n); }
+    idx_class_type idx_class (void) const { return m_rep->idx_class (); }
 
-  octave_idx_type xelem (octave_idx_type n) const
-  { return m_rep->xelem (n); }
-
-  octave_idx_type checkelem (octave_idx_type n) const
-  { return m_rep->xelem (n); }
+    octave_idx_type length (octave_idx_type n = 0) const
+    { return m_rep->length (n); }
 
-  octave_idx_type operator () (octave_idx_type n) const
-  { return m_rep->xelem (n); }
+    octave_idx_type extent (octave_idx_type n) const
+    { return m_rep->extent (n); }
 
-  // FIXME: idx_vector objects are either created successfully or an
-  // error is thrown, so this method no longer makes sense.
-  operator bool (void) const { return true; }
+    octave_idx_type xelem (octave_idx_type n) const
+    { return m_rep->xelem (n); }
 
-  bool is_colon (void) const
-  { return m_rep->idx_class () == class_colon; }
-
-  bool is_scalar (void) const
-  { return m_rep->idx_class () == class_scalar; }
+    octave_idx_type checkelem (octave_idx_type n) const
+    { return m_rep->xelem (n); }
 
-  bool is_range (void) const
-  { return m_rep->idx_class () == class_range; }
+    octave_idx_type operator () (octave_idx_type n) const
+    { return m_rep->xelem (n); }
 
-  bool is_colon_equiv (octave_idx_type n) const
-  { return m_rep->is_colon_equiv (n); }
+    // FIXME: idx_vector objects are either created successfully or an
+    // error is thrown, so this method no longer makes sense.
+    operator bool (void) const { return true; }
 
-  idx_vector sorted (bool uniq = false) const
-  { return idx_vector (m_rep->sort_uniq_clone (uniq)); }
+    bool is_colon (void) const
+    { return m_rep->idx_class () == class_colon; }
+
+    bool is_scalar (void) const
+    { return m_rep->idx_class () == class_scalar; }
 
-  idx_vector sorted (Array<octave_idx_type>& sidx) const
-  { return idx_vector (m_rep->sort_idx (sidx)); }
+    bool is_range (void) const
+    { return m_rep->idx_class () == class_range; }
 
-  dim_vector orig_dimensions (void) const { return m_rep->orig_dimensions (); }
-
-  octave_idx_type orig_rows (void) const
-  { return orig_dimensions () (0); }
+    bool is_colon_equiv (octave_idx_type n) const
+    { return m_rep->is_colon_equiv (n); }
 
-  octave_idx_type orig_columns (void) const
-  { return orig_dimensions () (1); }
+    idx_vector sorted (bool uniq = false) const
+    { return idx_vector (m_rep->sort_uniq_clone (uniq)); }
 
-  int orig_empty (void) const
-  { return (! is_colon () && orig_dimensions ().any_zero ()); }
+    idx_vector sorted (Array<octave_idx_type>& sidx) const
+    { return idx_vector (m_rep->sort_idx (sidx)); }
 
-  // i/o
+    dim_vector orig_dimensions (void) const { return m_rep->orig_dimensions (); }
 
-  std::ostream& print (std::ostream& os) const { return m_rep->print (os); }
+    octave_idx_type orig_rows (void) const
+    { return orig_dimensions () (0); }
 
-  friend std::ostream& operator << (std::ostream& os, const idx_vector& a)
-  { return a.print (os); }
+    octave_idx_type orig_columns (void) const
+    { return orig_dimensions () (1); }
 
-  // Slice with specializations.  No checking of bounds!
-  //
-  // This is equivalent to the following loop (but much faster):
-  //
-  // for (octave_idx_type i = 0; i < idx->length (n); i++)
-  //   dest[i] = src[idx(i)];
-  // return i;
-  //
-  template <typename T>
-  octave_idx_type
-  index (const T *src, octave_idx_type n, T *dest) const
-  {
-    octave_idx_type len = m_rep->length (n);
+    int orig_empty (void) const
+    { return (! is_colon () && orig_dimensions ().any_zero ()); }
+
+    // i/o
 
-    switch (m_rep->idx_class ())
-      {
-      case class_colon:
-        std::copy_n (src, len, dest);
-        break;
+    std::ostream& print (std::ostream& os) const { return m_rep->print (os); }
+
+    friend std::ostream& operator << (std::ostream& os, const idx_vector& a)
+    { return a.print (os); }
 
-      case class_range:
+    // Slice with specializations.  No checking of bounds!
+    //
+    // This is equivalent to the following loop (but much faster):
+    //
+    // for (octave_idx_type i = 0; i < idx->length (n); i++)
+    //   dest[i] = src[idx(i)];
+    // return i;
+    //
+    template <typename T>
+    octave_idx_type
+    index (const T *src, octave_idx_type n, T *dest) const
+    {
+      octave_idx_type len = m_rep->length (n);
+
+      switch (m_rep->idx_class ())
         {
-          idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
-          octave_idx_type start = r->get_start ();
-          octave_idx_type step = r->get_step ();
-          const T *ssrc = src + start;
-          if (step == 1)
-            std::copy_n (ssrc, len, dest);
-          else if (step == -1)
-            std::reverse_copy (ssrc - len + 1, ssrc + 1, dest);
-          else if (step == 0)
-            std::fill_n (dest, len, *ssrc);
-          else
-            {
-              for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
-                dest[i] = ssrc[j];
-            }
-        }
-        break;
+        case class_colon:
+          std::copy_n (src, len, dest);
+          break;
 
-      case class_scalar:
-        {
-          idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
-          dest[0] = src[r->get_data ()];
-        }
-        break;
+        case class_range:
+          {
+            idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
+            octave_idx_type start = r->get_start ();
+            octave_idx_type step = r->get_step ();
+            const T *ssrc = src + start;
+            if (step == 1)
+              std::copy_n (ssrc, len, dest);
+            else if (step == -1)
+              std::reverse_copy (ssrc - len + 1, ssrc + 1, dest);
+            else if (step == 0)
+              std::fill_n (dest, len, *ssrc);
+            else
+              {
+                for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
+                  dest[i] = ssrc[j];
+              }
+          }
+          break;
 
-      case class_vector:
-        {
-          idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
-          const octave_idx_type *data = r->get_data ();
-          for (octave_idx_type i = 0; i < len; i++)
-            dest[i] = src[data[i]];
-        }
-        break;
-
-      case class_mask:
-        {
-          idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
-          const bool *data = r->get_data ();
-          octave_idx_type ext = r->extent (0);
-          for (octave_idx_type i = 0; i < ext; i++)
-            if (data[i]) *dest++ = src[i];
-        }
-        break;
+        case class_scalar:
+          {
+            idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
+            dest[0] = src[r->get_data ()];
+          }
+          break;
 
-      default:
-        assert (false);
-        break;
-      }
+        case class_vector:
+          {
+            idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
+            const octave_idx_type *data = r->get_data ();
+            for (octave_idx_type i = 0; i < len; i++)
+              dest[i] = src[data[i]];
+          }
+          break;
 
-    return len;
-  }
+        case class_mask:
+          {
+            idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
+            const bool *data = r->get_data ();
+            octave_idx_type ext = r->extent (0);
+            for (octave_idx_type i = 0; i < ext; i++)
+              if (data[i]) *dest++ = src[i];
+          }
+          break;
 
-  // Slice assignment with specializations.  No checking of bounds!
-  //
-  // This is equivalent to the following loop (but much faster):
-  //
-  // for (octave_idx_type i = 0; i < idx->length (n); i++)
-  //   dest[idx(i)] = src[i];
-  // return i;
-  //
-  template <typename T>
-  octave_idx_type
-  assign (const T *src, octave_idx_type n, T *dest) const
-  {
-    octave_idx_type len = m_rep->length (n);
+        default:
+          assert (false);
+          break;
+        }
+
+      return len;
+    }
 
-    switch (m_rep->idx_class ())
-      {
-      case class_colon:
-        std::copy_n (src, len, dest);
-        break;
+    // Slice assignment with specializations.  No checking of bounds!
+    //
+    // This is equivalent to the following loop (but much faster):
+    //
+    // for (octave_idx_type i = 0; i < idx->length (n); i++)
+    //   dest[idx(i)] = src[i];
+    // return i;
+    //
+    template <typename T>
+    octave_idx_type
+    assign (const T *src, octave_idx_type n, T *dest) const
+    {
+      octave_idx_type len = m_rep->length (n);
 
-      case class_range:
+      switch (m_rep->idx_class ())
         {
-          idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
-          octave_idx_type start = r->get_start ();
-          octave_idx_type step = r->get_step ();
-          T *sdest = dest + start;
-          if (step == 1)
-            std::copy_n (src, len, sdest);
-          else if (step == -1)
-            std::reverse_copy (src, src + len, sdest - len + 1);
-          else
-            {
-              for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
-                sdest[j] = src[i];
-            }
-        }
-        break;
+        case class_colon:
+          std::copy_n (src, len, dest);
+          break;
 
-      case class_scalar:
-        {
-          idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
-          dest[r->get_data ()] = src[0];
-        }
-        break;
+        case class_range:
+          {
+            idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
+            octave_idx_type start = r->get_start ();
+            octave_idx_type step = r->get_step ();
+            T *sdest = dest + start;
+            if (step == 1)
+              std::copy_n (src, len, sdest);
+            else if (step == -1)
+              std::reverse_copy (src, src + len, sdest - len + 1);
+            else
+              {
+                for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
+                  sdest[j] = src[i];
+              }
+          }
+          break;
 
-      case class_vector:
-        {
-          idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
-          const octave_idx_type *data = r->get_data ();
-          for (octave_idx_type i = 0; i < len; i++)
-            dest[data[i]] = src[i];
-        }
-        break;
+        case class_scalar:
+          {
+            idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
+            dest[r->get_data ()] = src[0];
+          }
+          break;
 
-      case class_mask:
-        {
-          idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
-          const bool *data = r->get_data ();
-          octave_idx_type ext = r->extent (0);
-          for (octave_idx_type i = 0; i < ext; i++)
-            if (data[i]) dest[i] = *src++;
-        }
-        break;
+        case class_vector:
+          {
+            idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
+            const octave_idx_type *data = r->get_data ();
+            for (octave_idx_type i = 0; i < len; i++)
+              dest[data[i]] = src[i];
+          }
+          break;
 
-      default:
-        assert (false);
-        break;
-      }
-
-    return len;
-  }
+        case class_mask:
+          {
+            idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
+            const bool *data = r->get_data ();
+            octave_idx_type ext = r->extent (0);
+            for (octave_idx_type i = 0; i < ext; i++)
+              if (data[i]) dest[i] = *src++;
+          }
+          break;
 
-  // Slice fill with specializations.  No checking of bounds!
-  //
-  // This is equivalent to the following loop (but much faster):
-  //
-  // for (octave_idx_type i = 0; i < idx->length (n); i++)
-  //   dest[idx(i)] = val;
-  // return i;
-  //
-  template <typename T>
-  octave_idx_type
-  fill (const T& val, octave_idx_type n, T *dest) const
-  {
-    octave_idx_type len = m_rep->length (n);
+        default:
+          assert (false);
+          break;
+        }
+
+      return len;
+    }
 
-    switch (m_rep->idx_class ())
-      {
-      case class_colon:
-        std::fill_n (dest, len, val);
-        break;
+    // Slice fill with specializations.  No checking of bounds!
+    //
+    // This is equivalent to the following loop (but much faster):
+    //
+    // for (octave_idx_type i = 0; i < idx->length (n); i++)
+    //   dest[idx(i)] = val;
+    // return i;
+    //
+    template <typename T>
+    octave_idx_type
+    fill (const T& val, octave_idx_type n, T *dest) const
+    {
+      octave_idx_type len = m_rep->length (n);
 
-      case class_range:
+      switch (m_rep->idx_class ())
         {
-          idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
-          octave_idx_type start = r->get_start ();
-          octave_idx_type step = r->get_step ();
-          T *sdest = dest + start;
-          if (step == 1)
-            std::fill_n (sdest, len, val);
-          else if (step == -1)
-            std::fill (sdest - len + 1, sdest + 1, val);
-          else
-            {
-              for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
-                sdest[j] = val;
-            }
-        }
-        break;
+        case class_colon:
+          std::fill_n (dest, len, val);
+          break;
+
+        case class_range:
+          {
+            idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
+            octave_idx_type start = r->get_start ();
+            octave_idx_type step = r->get_step ();
+            T *sdest = dest + start;
+            if (step == 1)
+              std::fill_n (sdest, len, val);
+            else if (step == -1)
+              std::fill (sdest - len + 1, sdest + 1, val);
+            else
+              {
+                for (octave_idx_type i = 0, j = 0; i < len; i++, j += step)
+                  sdest[j] = val;
+              }
+          }
+          break;
 
-      case class_scalar:
-        {
-          idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
-          dest[r->get_data ()] = val;
-        }
-        break;
+        case class_scalar:
+          {
+            idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
+            dest[r->get_data ()] = val;
+          }
+          break;
 
-      case class_vector:
-        {
-          idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
-          const octave_idx_type *data = r->get_data ();
-          for (octave_idx_type i = 0; i < len; i++)
-            dest[data[i]] = val;
+        case class_vector:
+          {
+            idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
+            const octave_idx_type *data = r->get_data ();
+            for (octave_idx_type i = 0; i < len; i++)
+              dest[data[i]] = val;
+          }
+          break;
+
+        case class_mask:
+          {
+            idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
+            const bool *data = r->get_data ();
+            octave_idx_type ext = r->extent (0);
+            for (octave_idx_type i = 0; i < ext; i++)
+              if (data[i]) dest[i] = val;
+          }
+          break;
+
+        default:
+          assert (false);
+          break;
         }
-        break;
 
-      case class_mask:
-        {
-          idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
-          const bool *data = r->get_data ();
-          octave_idx_type ext = r->extent (0);
-          for (octave_idx_type i = 0; i < ext; i++)
-            if (data[i]) dest[i] = val;
-        }
-        break;
+      return len;
+    }
 
-      default:
-        assert (false);
-        break;
-      }
-
-    return len;
-  }
+    // Generic non-breakable indexed loop.  The loop body should be
+    // encapsulated in a single functor body.  This is equivalent to the
+    // following loop (but faster, at least for simple inlined bodies):
+    //
+    // for (octave_idx_type i = 0; i < idx->length (n); i++) body (idx(i));
 
-  // Generic non-breakable indexed loop.  The loop body should be
-  // encapsulated in a single functor body.  This is equivalent to the
-  // following loop (but faster, at least for simple inlined bodies):
-  //
-  // for (octave_idx_type i = 0; i < idx->length (n); i++) body (idx(i));
-
-  template <typename Functor>
-  void
-  loop (octave_idx_type n, Functor body) const
-  {
-    octave_idx_type len = m_rep->length (n);
+    template <typename Functor>
+    void
+    loop (octave_idx_type n, Functor body) const
+    {
+      octave_idx_type len = m_rep->length (n);
 
-    switch (m_rep->idx_class ())
-      {
-      case class_colon:
-        for (octave_idx_type i = 0; i < len; i++) body (i);
-        break;
-
-      case class_range:
+      switch (m_rep->idx_class ())
         {
-          idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
-          octave_idx_type start = r->get_start ();
-          octave_idx_type step = r->get_step ();
-          octave_idx_type i, j;
-          if (step == 1)
-            for (i = start, j = start + len; i < j; i++) body (i);
-          else if (step == -1)
-            for (i = start, j = start - len; i > j; i--) body (i);
-          else
-            for (i = 0, j = start; i < len; i++, j += step) body (j);
-        }
-        break;
+        case class_colon:
+          for (octave_idx_type i = 0; i < len; i++) body (i);
+          break;
 
-      case class_scalar:
-        {
-          idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
-          body (r->get_data ());
-        }
-        break;
+        case class_range:
+          {
+            idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
+            octave_idx_type start = r->get_start ();
+            octave_idx_type step = r->get_step ();
+            octave_idx_type i, j;
+            if (step == 1)
+              for (i = start, j = start + len; i < j; i++) body (i);
+            else if (step == -1)
+              for (i = start, j = start - len; i > j; i--) body (i);
+            else
+              for (i = 0, j = start; i < len; i++, j += step) body (j);
+          }
+          break;
 
-      case class_vector:
-        {
-          idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
-          const octave_idx_type *data = r->get_data ();
-          for (octave_idx_type i = 0; i < len; i++) body (data[i]);
-        }
-        break;
+        case class_scalar:
+          {
+            idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
+            body (r->get_data ());
+          }
+          break;
 
-      case class_mask:
-        {
-          idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
-          const bool *data = r->get_data ();
-          octave_idx_type ext = r->extent (0);
-          for (octave_idx_type i = 0; i < ext; i++)
-            if (data[i]) body (i);
-        }
-        break;
+        case class_vector:
+          {
+            idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
+            const octave_idx_type *data = r->get_data ();
+            for (octave_idx_type i = 0; i < len; i++) body (data[i]);
+          }
+          break;
 
-      default:
-        assert (false);
-        break;
-      }
-
-  }
+        case class_mask:
+          {
+            idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
+            const bool *data = r->get_data ();
+            octave_idx_type ext = r->extent (0);
+            for (octave_idx_type i = 0; i < ext; i++)
+              if (data[i]) body (i);
+          }
+          break;
 
-  // Generic breakable indexed loop.  The loop body should be
-  // encapsulated in a single functor body.  This is equivalent to the
-  // following loop (but faster, at least for simple inlined bodies):
-  //
-  // for (octave_idx_type i = 0; i < idx->length (n); i++)
-  //   if (body (idx(i))) break;
-  // return i;
-  //
+        default:
+          assert (false);
+          break;
+        }
+
+    }
 
-  template <typename Functor>
-  octave_idx_type
-  bloop (octave_idx_type n, Functor body) const
-  {
-    octave_idx_type len = m_rep->length (n), ret;
+    // Generic breakable indexed loop.  The loop body should be
+    // encapsulated in a single functor body.  This is equivalent to the
+    // following loop (but faster, at least for simple inlined bodies):
+    //
+    // for (octave_idx_type i = 0; i < idx->length (n); i++)
+    //   if (body (idx(i))) break;
+    // return i;
+    //
 
-    switch (m_rep->idx_class ())
-      {
-      case class_colon:
+    template <typename Functor>
+    octave_idx_type
+    bloop (octave_idx_type n, Functor body) const
+    {
+      octave_idx_type len = m_rep->length (n), ret;
+
+      switch (m_rep->idx_class ())
         {
-          octave_idx_type i;
-          for (i = 0; i < len && body (i); i++) ;
-          ret = i;
-        }
-        break;
+        case class_colon:
+          {
+            octave_idx_type i;
+            for (i = 0; i < len && body (i); i++) ;
+            ret = i;
+          }
+          break;
 
-      case class_range:
-        {
-          idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
-          octave_idx_type start = r->get_start ();
-          octave_idx_type step = r->get_step ();
-          octave_idx_type i, j;
-          if (step == 1)
-            for (i = start, j = start + len; i < j && body (i); i++) ;
-          else if (step == -1)
-            for (i = start, j = start - len; i > j && body (i); i--) ;
-          else
-            for (i = 0, j = start; i < len && body (j); i++, j += step) ;
-          ret = i;
-        }
-        break;
+        case class_range:
+          {
+            idx_range_rep *r = dynamic_cast<idx_range_rep *> (m_rep);
+            octave_idx_type start = r->get_start ();
+            octave_idx_type step = r->get_step ();
+            octave_idx_type i, j;
+            if (step == 1)
+              for (i = start, j = start + len; i < j && body (i); i++) ;
+            else if (step == -1)
+              for (i = start, j = start - len; i > j && body (i); i--) ;
+            else
+              for (i = 0, j = start; i < len && body (j); i++, j += step) ;
+            ret = i;
+          }
+          break;
 
-      case class_scalar:
-        {
-          idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
-          ret = (body (r->get_data ()) ? 1 : 0);
-        }
-        break;
+        case class_scalar:
+          {
+            idx_scalar_rep *r = dynamic_cast<idx_scalar_rep *> (m_rep);
+            ret = (body (r->get_data ()) ? 1 : 0);
+          }
+          break;
 
-      case class_vector:
-        {
-          idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
-          const octave_idx_type *data = r->get_data ();
-          octave_idx_type i;
-          for (i = 0; i < len && body (data[i]); i++) ;
-          ret = i;
-        }
-        break;
+        case class_vector:
+          {
+            idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
+            const octave_idx_type *data = r->get_data ();
+            octave_idx_type i;
+            for (i = 0; i < len && body (data[i]); i++) ;
+            ret = i;
+          }
+          break;
 
-      case class_mask:
-        {
-          idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
-          const bool *data = r->get_data ();
-          octave_idx_type ext = r->extent (0);
-          octave_idx_type j = 0;
-          for (octave_idx_type i = 0; i < ext; i++)
-            {
-              if (data[i])
-                {
-                  if (body (i))
-                    break;
-                  else
-                    j++;
-                }
-            }
+        case class_mask:
+          {
+            idx_mask_rep *r = dynamic_cast<idx_mask_rep *> (m_rep);
+            const bool *data = r->get_data ();
+            octave_idx_type ext = r->extent (0);
+            octave_idx_type j = 0;
+            for (octave_idx_type i = 0; i < ext; i++)
+              {
+                if (data[i])
+                  {
+                    if (body (i))
+                      break;
+                    else
+                      j++;
+                  }
+              }
 
-          ret = j;
-        }
-        break;
+            ret = j;
+          }
+          break;
 
-      default:
-        assert (false);
-        break;
-      }
+        default:
+          assert (false);
+          break;
+        }
 
-    return ret;
-  }
+      return ret;
+    }
 
-  // Rationale:
-  // This method is the key to "smart indexing".  When indexing cartesian
-  // arrays, sometimes consecutive index vectors can be reduced into a
-  // single index.  If rows (A) = k and i.maybe_reduce (j) gives k, then
-  // A(i,j)(:) is equal to A(k)(:).
+    // Rationale:
+    // This method is the key to "smart indexing".  When indexing cartesian
+    // arrays, sometimes consecutive index vectors can be reduced into a
+    // single index.  If rows (A) = k and i.maybe_reduce (j) gives k, then
+    // A(i,j)(:) is equal to A(k)(:).
 
-  // If the next index can be reduced, returns true and updates this.
-  bool maybe_reduce (octave_idx_type n, const idx_vector& j,
-                     octave_idx_type nj);
+    // If the next index can be reduced, returns true and updates this.
+    bool maybe_reduce (octave_idx_type n, const idx_vector& j,
+                       octave_idx_type nj);
 
-  bool is_cont_range (octave_idx_type n,
-                      octave_idx_type& l, octave_idx_type& u) const;
+    bool is_cont_range (octave_idx_type n,
+                        octave_idx_type& l, octave_idx_type& u) const;
+
+    // Returns the increment for ranges and colon, 0 for scalars and empty
+    // vectors, 1st difference otherwise.
+    octave_idx_type increment (void) const;
 
-  // Returns the increment for ranges and colon, 0 for scalars and empty
-  // vectors, 1st difference otherwise.
-  octave_idx_type increment (void) const;
+    idx_vector
+    complement (octave_idx_type n) const;
 
-  idx_vector
-  complement (octave_idx_type n) const;
+    bool is_permutation (octave_idx_type n) const;
 
-  bool is_permutation (octave_idx_type n) const;
+    // Returns the inverse permutation.  If this is not a permutation on 1:n, the
+    // result is undefined (but no error unless extent () != n).
+    idx_vector inverse_permutation (octave_idx_type n) const;
 
-  // Returns the inverse permutation.  If this is not a permutation on 1:n, the
-  // result is undefined (but no error unless extent () != n).
-  idx_vector inverse_permutation (octave_idx_type n) const;
+    // Copies all the indices to a given array.  Not allowed for colons.
+    void copy_data (octave_idx_type *data) const;
 
-  // Copies all the indices to a given array.  Not allowed for colons.
-  void copy_data (octave_idx_type *data) const;
+    // If the index is a mask, convert it to index vector.
+    idx_vector unmask (void) const;
 
-  // If the index is a mask, convert it to index vector.
-  idx_vector unmask (void) const;
+    // Unconverts the index to a scalar, Range, double array or a mask.
+    void unconvert (idx_class_type& iclass,
+                    double& scalar, range<double>& range,
+                    Array<double>& array, Array<bool>& mask) const;
 
-  // Unconverts the index to a scalar, Range, double array or a mask.
-  void unconvert (idx_class_type& iclass,
-                  double& scalar, octave::range<double>& range,
-                  Array<double>& array, Array<bool>& mask) const;
+    Array<octave_idx_type> as_array (void) const;
 
-  Array<octave_idx_type> as_array (void) const;
+    // Raw pointer to index array.  This is non-const because it may be
+    // necessary to mutate the index.
+    const octave_idx_type * raw (void);
+
+    bool isvector (void) const;
 
-  // Raw pointer to index array.  This is non-const because it may be
-  // necessary to mutate the index.
-  const octave_idx_type * raw (void);
-
-  bool isvector (void) const;
+    // FIXME: these are here for compatibility.  They should be removed
+    // when no longer in use.
 
-  // FIXME: these are here for compatibility.  They should be removed
-  // when no longer in use.
+    octave_idx_type elem (octave_idx_type n) const
+    { return (*this) (n); }
 
-  octave_idx_type elem (octave_idx_type n) const
-  { return (*this) (n); }
+    bool is_colon_equiv (octave_idx_type n, int) const
+    { return is_colon_equiv (n); }
 
-  bool is_colon_equiv (octave_idx_type n, int) const
-  { return is_colon_equiv (n); }
+    octave_idx_type
+    freeze (octave_idx_type z_len, const char *tag, bool resize_ok = false);
 
-  octave_idx_type
-  freeze (octave_idx_type z_len, const char *tag, bool resize_ok = false);
+    void sort (bool uniq = false)
+    { *this = sorted (uniq); }
 
-  void sort (bool uniq = false)
-  { *this = sorted (uniq); }
+    octave_idx_type ones_count (void) const;
+
+    octave_idx_type max (void) const { return extent (1) - 1; }
 
-  octave_idx_type ones_count (void) const;
+    private:
 
-  octave_idx_type max (void) const { return extent (1) - 1; }
+    idx_base_rep *m_rep;
 
-private:
+  };
+}
 
-  idx_base_rep *m_rep;
+// Provide the following typedef for backward compatibility.  Don't
+// deprecate (yet) because it is used extensively.
 
-};
+typedef octave::idx_vector idx_vector;
 
 #endif
--- a/liboctave/numeric/oct-convn.cc	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/numeric/oct-convn.cc	Wed Apr 28 13:46:02 2021 -0400
@@ -168,10 +168,10 @@
   if (ct == convn_same)
     {
       // Pick the relevant part.
-      Array<idx_vector> sidx (dim_vector (nd, 1));
+      Array<octave::idx_vector> sidx (dim_vector (nd, 1));
 
       for (int i = 0; i < nd; i++)
-        sidx(i) = idx_vector::make_range (bdims(i)/2, 1, adims(i));
+        sidx(i) = octave::idx_vector::make_range (bdims(i)/2, 1, adims(i));
       c = c.index (sidx);
     }
 
--- a/liboctave/operators/mx-op-defs.h	Wed Apr 28 12:55:19 2021 -0400
+++ b/liboctave/operators/mx-op-defs.h	Wed Apr 28 13:46:02 2021 -0400
@@ -607,7 +607,7 @@
     else                                                                \
       {                                                                 \
         result = M (nr, nc);                                            \
-        result.assign (p.col_perm_vec (), idx_vector::colon, x);        \
+        result.assign (p.col_perm_vec (), octave::idx_vector::colon, x);        \
       }                                                                 \
                                                                         \
     return result;                                                      \
@@ -622,7 +622,7 @@
     if (p.rows () != nc)                                                \
       octave::err_nonconformant ("operator *", nr, nc, p.rows (), p.columns ()); \
                                                                         \
-    result = x.index (idx_vector::colon, p.col_perm_vec ());            \
+    result = x.index (octave::idx_vector::colon, p.col_perm_vec ());            \
                                                                         \
     return result;                                                      \
   }