changeset 28631:70cdf8de553d

move non-member octave_value operator functions to octave namespace * ov.h, ov.cc (unary_op, binary_op, cat_op, colon_op): New functions in octave namespace that replace do_unary_op, do_binary_op, do_cat_op, and do_colon_op, respectively. (do_unary_op, do_binary_op, do_cat_op, do_colon_op): Deprecate global functions. Forward to corresponding new functions in octave namespace. * bsxfun.cc, cellfun.cc, data.cc, dot.cc, fft.cc, oct-stream.cc, stack-frame.h, tril.cc, ov-base-diag.cc, ov-bool.cc, ov-class.cc, ov-complex.cc, ov-float.cc, ov-flt-complex.cc, ov-intx.h, ov-lazy-idx.h, ov-magic-int.cc, ov-perm.cc, ov-range.cc, ov-scalar.cc, oct-lvalue.cc, oct-lvalue.h, pt-binop.cc, pt-cbinop.cc, pt-colon.cc, pt-eval.cc, pt-tm-const.cc, pt-unop.cc: Change all uses.
author John W. Eaton <jwe@octave.org>
date Thu, 30 Jul 2020 16:16:04 -0400
parents 35f974bab4c8
children 6aa0808d2ed6
files libinterp/corefcn/bsxfun.cc libinterp/corefcn/cellfun.cc libinterp/corefcn/data.cc libinterp/corefcn/dot.cc libinterp/corefcn/fft.cc libinterp/corefcn/oct-stream.cc libinterp/corefcn/stack-frame.h libinterp/corefcn/tril.cc libinterp/octave-value/ov-base-diag.cc libinterp/octave-value/ov-bool.cc libinterp/octave-value/ov-class.cc libinterp/octave-value/ov-complex.cc libinterp/octave-value/ov-float.cc libinterp/octave-value/ov-flt-complex.cc libinterp/octave-value/ov-intx.h libinterp/octave-value/ov-lazy-idx.h libinterp/octave-value/ov-magic-int.cc libinterp/octave-value/ov-perm.cc libinterp/octave-value/ov-range.cc libinterp/octave-value/ov-scalar.cc libinterp/octave-value/ov.cc libinterp/octave-value/ov.h libinterp/parse-tree/oct-lvalue.cc libinterp/parse-tree/oct-lvalue.h libinterp/parse-tree/pt-binop.cc libinterp/parse-tree/pt-cbinop.cc libinterp/parse-tree/pt-colon.cc libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-tm-const.cc libinterp/parse-tree/pt-unop.cc
diffstat 30 files changed, 747 insertions(+), 665 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/bsxfun.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/corefcn/bsxfun.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -540,7 +540,7 @@
                         {
                           have_NDArray = false;
                           C = result_NDArray;
-                          C = do_cat_op (C, tmp(0), ra_idx);
+                          C = octave::cat_op (C, tmp(0), ra_idx);
                         }
                       else if (tmp(0).isreal ())
                         result_NDArray.insert (tmp(0).array_value (), ra_idx);
@@ -560,7 +560,7 @@
                         {
                           have_FloatNDArray = false;
                           C = result_FloatNDArray;
-                          C = do_cat_op (C, tmp(0), ra_idx);
+                          C = octave::cat_op (C, tmp(0), ra_idx);
                         }
                       else if (tmp(0).isreal ())
                         result_FloatNDArray.insert
@@ -583,7 +583,7 @@
                         {                                               \
                           have_ ## T = false;                           \
                           C = result_ ## T;                             \
-                          C = do_cat_op (C, tmp(0), ra_idx);            \
+                          C = octave::cat_op (C, tmp(0), ra_idx);       \
                         }                                               \
                       else                                              \
                         result_ ## T .insert (tmp(0). EXTRACTOR ## _array_value (), ra_idx); \
@@ -601,7 +601,7 @@
                   else if BSXLOOP(uint32NDArray, "uint32", uint32)
                   else if BSXLOOP(uint64NDArray, "uint64", uint64)
                   else
-                    C = do_cat_op (C, tmp(0), ra_idx);
+                    C = octave::cat_op (C, tmp(0), ra_idx);
                 }
             }
 
--- a/libinterp/corefcn/cellfun.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/corefcn/cellfun.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -1244,7 +1244,7 @@
               for (int j = 0; j < nargin; j++)
                 {
                   if (mask[j])
-                    inputlist.xelem (j) = inputs[j].do_index_op (idx_list);
+                    inputlist.xelem (j) = inputs[j].index_op (idx_list);
                 }
 
               const octave_value_list tmp
@@ -1336,7 +1336,7 @@
               for (int j = 0; j < nargin; j++)
                 {
                   if (mask[j])
-                    inputlist.xelem (j) = inputs[j].do_index_op (idx_list);
+                    inputlist.xelem (j) = inputs[j].index_op (idx_list);
                 }
 
               const octave_value_list tmp
@@ -2085,7 +2085,7 @@
       for (int i = 0; i < nd; i++)
         ra_idx(i) = idx[i][ridx[i]];
 
-      retval.xelem (j) = a.do_index_op (ra_idx);
+      retval.xelem (j) = a.index_op (ra_idx);
 
       rdv.increment_index (ridx);
     }
@@ -2420,7 +2420,7 @@
       for (octave_idx_type i = 0; i < n; i++)
         {
           idx(dim) = Range (lb(i), ub(i));
-          retcell.xelem (i) = x.do_index_op (idx);
+          retcell.xelem (i) = x.index_op (idx);
         }
     }
 
@@ -2471,7 +2471,7 @@
 
       octave_value tmp = x(i);
 
-      y.xelem (i) = tmp.do_index_op (idx);
+      y.xelem (i) = tmp.index_op (idx);
     }
 
   return octave_value (y);
--- a/libinterp/corefcn/data.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/corefcn/data.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -1955,7 +1955,7 @@
               // Can't fast return here to skip empty matrices as something
               // like cat (1,[],single ([])) must return an empty matrix of
               // the right type.
-              tmp = do_cat_op (tmp, args(j), ra_idx);
+              tmp = octave::cat_op (tmp, args(j), ra_idx);
 
               dim_vector dv_tmp = args(j).dims ();
 
@@ -5955,7 +5955,7 @@
   if (args.length () != 1)
     print_usage ();
 
-  return do_unary_op (op, args(0));
+  return octave::unary_op (op, args(0));
 }
 
 DEFUN (not, args, ,
@@ -6061,7 +6061,7 @@
   if (args.length () != 2)
     print_usage ();
 
-  return do_binary_op (op, args(0), args(1));
+  return octave::binary_op (op, args(0), args(1));
 }
 
 static octave_value
@@ -6077,10 +6077,10 @@
   octave_value retval;
 
   if (nargin == 2)
-    retval = do_binary_op (op, args(0), args(1));
+    retval = octave::binary_op (op, args(0), args(1));
   else
     {
-      retval = do_binary_op (op, args(0), args(1));
+      retval = octave::binary_op (op, args(0), args(1));
 
       for (int i = 2; i < nargin; i++)
         retval.assign (aop, args(i));
@@ -6375,8 +6375,9 @@
   if (nargin < 2 || nargin > 3)
     print_usage ();
 
-  return (nargin == 2 ? do_colon_op (args(0), args(1))
-                      : do_colon_op (args(0), args(1), args(2)));
+  return (nargin == 2
+          ? octave::colon_op (args(0), args(1))
+          : octave::colon_op (args(0), args(1), args(2)));
 }
 
 static double tic_toc_timestamp = -1.0;
--- a/libinterp/corefcn/dot.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/corefcn/dot.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -190,7 +190,7 @@
       // exceed intmax.
       octave_value_list tmp;
       tmp(1) = dim + 1;
-      tmp(0) = do_binary_op (octave_value::op_el_mul, argx, argy);
+      tmp(0) = octave::binary_op (octave_value::op_el_mul, argx, argy);
 
       tmp = Fsum (tmp, 1);
       if (! tmp.empty ())
--- a/libinterp/corefcn/fft.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/corefcn/fft.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -113,7 +113,7 @@
         idx(i) = idx_vector::colon;
       idx(dim) = idx_vector (static_cast<octave_idx_type> (0));
 
-      return arg.do_index_op (idx);
+      return arg.index_op (idx);
     }
 
   if (arg.is_single_type ())
--- a/libinterp/corefcn/oct-stream.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/corefcn/oct-stream.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -2714,8 +2714,8 @@
               dv = dim_vector (std::max (valid_rows - 1, 0), 1);
 
             ra_idx(1) = i;
-            retval = do_cat_op (retval, octave_value (Cell (col.resize (dv,0))),
-                                ra_idx);
+            retval = cat_op (retval, octave_value (Cell (col.resize (dv,0))),
+                             ra_idx);
             i++;
           }
       }
@@ -2734,8 +2734,7 @@
                 if (prev_type != -1)
                   {
                     ra_idx(1) = i++;
-                    retval = do_cat_op (retval, octave_value (Cell (cur)),
-                                        ra_idx);
+                    retval = cat_op (retval, octave_value (Cell (cur)), ra_idx);
                   }
                 cur = octave_value (col.resize (dv,0));
                 group_size = 1;
@@ -2744,12 +2743,11 @@
             else
               {
                 ra_idx(1) = group_size++;
-                cur = do_cat_op (cur, octave_value (col.resize (dv,0)),
-                                 ra_idx);
+                cur = cat_op (cur, octave_value (col.resize (dv,0)), ra_idx);
               }
           }
         ra_idx(1) = i;
-        retval = do_cat_op (retval, octave_value (Cell (cur)), ra_idx);
+        retval = cat_op (retval, octave_value (Cell (cur)), ra_idx);
       }
 
     return retval;
@@ -3276,7 +3274,7 @@
                     else
                       {
                         if (ov.isreal ())  // cat does type conversion
-                          ov = do_cat_op (ov, octave_value (v), row);
+                          ov = cat_op (ov, octave_value (v), row);
                         else
                           ov.internal_rep ()->fast_elem_insert (row(0), v);
                       }
@@ -3289,7 +3287,7 @@
                     else
                       {
                         if (ov.isreal ())  // cat does type conversion
-                          ov = do_cat_op (ov, octave_value (v), row);
+                          ov = cat_op (ov, octave_value (v), row);
                         else
                           ov.internal_rep ()->fast_elem_insert (row(0),
                                                                 FloatComplex (v));
@@ -3374,7 +3372,7 @@
           }
 
         if (is.fail () & ! fmt.discard)
-          ov = do_cat_op (ov, empty_value, row);
+          ov = cat_op (ov, empty_value, row);
       }
     else
       {
@@ -5716,7 +5714,7 @@
         // Easier than dispatching here...
 
         octave_value ov_is_ge_zero
-          = do_binary_op (octave_value::op_ge, val, octave_value (0.0));
+          = binary_op (octave_value::op_ge, val, octave_value (0.0));
 
         return ov_is_ge_zero.is_true ();
       }
--- a/libinterp/corefcn/stack-frame.h	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/corefcn/stack-frame.h	Thu Jul 30 16:16:04 2020 -0400
@@ -465,15 +465,15 @@
         varref (sym).assign (op, type, idx, rhs);
     }
 
-    void do_non_const_unary_op (octave_value::unary_op op,
+    void non_const_unary_op (octave_value::unary_op op,
                                 const symbol_record& sym,
                                 const std::string& type,
                                 const std::list<octave_value_list>& idx)
     {
       if (idx.empty ())
-        varref (sym).do_non_const_unary_op (op);
+        varref (sym).non_const_unary_op (op);
       else
-        varref (sym).do_non_const_unary_op (op, type, idx);
+        varref (sym).non_const_unary_op (op, type, idx);
     }
 
     octave_value value (const symbol_record& sym, const std::string& type,
--- a/libinterp/corefcn/tril.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/corefcn/tril.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -290,7 +290,7 @@
         idx_tmp.push_back (ov_idx);
         ov_idx(1) = static_cast<double> (nc);
         tmp = tmp.resize (dim_vector (0,0));
-        tmp = tmp.subsasgn ("(", idx_tmp, arg.do_index_op (ov_idx));
+        tmp = tmp.subsasgn ("(", idx_tmp, arg.index_op (ov_idx));
         tmp = tmp.resize (dims);
 
         if (lower)
@@ -305,7 +305,7 @@
                 std::list<octave_value_list> idx;
                 idx.push_back (ov_idx);
 
-                tmp = tmp.subsasgn ("(", idx, arg.do_index_op (ov_idx));
+                tmp = tmp.subsasgn ("(", idx, arg.index_op (ov_idx));
               }
           }
         else
@@ -320,7 +320,7 @@
                 std::list<octave_value_list> idx;
                 idx.push_back (ov_idx);
 
-                tmp = tmp.subsasgn ("(", idx, arg.do_index_op (ov_idx));
+                tmp = tmp.subsasgn ("(", idx, arg.index_op (ov_idx));
               }
           }
 
--- a/libinterp/octave-value/ov-base-diag.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov-base-diag.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -130,7 +130,7 @@
                   retval = rm;
                 }
               else
-                retval = to_dense ().do_index_op (idx, resize_ok);
+                retval = to_dense ().index_op (idx, resize_ok);
             }
         }
       catch (octave::index_exception& e)
@@ -141,7 +141,7 @@
         }
     }
   else
-    retval = to_dense ().do_index_op (idx, resize_ok);
+    retval = to_dense ().index_op (idx, resize_ok);
 
   return retval;
 }
--- a/libinterp/octave-value/ov-bool.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov-bool.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -91,7 +91,7 @@
 
   octave_value tmp (new octave_bool_matrix (bool_matrix_value ()));
 
-  return tmp.do_index_op (idx, resize_ok);
+  return tmp.index_op (idx, resize_ok);
 }
 
 octave_value
--- a/libinterp/octave-value/ov-class.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov-class.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -838,8 +838,8 @@
   // (why this inconsistency Mathworks?), and so we must
   // add one to the value returned as the index_vector method
   // expects it to be one based.
-  return do_binary_op (octave_value::op_add, tmp (0),
-                       octave_value (1.0)).index_vector (require_integers);
+  return octave::binary_op (octave_value::op_add, tmp (0),
+                               octave_value (1.0)).index_vector (require_integers);
 }
 
 size_t
--- a/libinterp/octave-value/ov-complex.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov-complex.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -140,7 +140,7 @@
 
   octave_value tmp (new octave_complex_matrix (complex_matrix_value ()));
 
-  return tmp.do_index_op (idx, resize_ok);
+  return tmp.index_op (idx, resize_ok);
 }
 
 // Can't make an index_vector from a complex number.  Throw an error.
--- a/libinterp/octave-value/ov-float.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov-float.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -79,7 +79,7 @@
 
   octave_value tmp (new octave_float_matrix (float_matrix_value ()));
 
-  return tmp.do_index_op (idx, resize_ok);
+  return tmp.index_op (idx, resize_ok);
 }
 
 octave_value
--- a/libinterp/octave-value/ov-flt-complex.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov-flt-complex.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -91,7 +91,7 @@
 
   octave_value tmp (new octave_float_complex_matrix (float_complex_matrix_value ()));
 
-  return tmp.do_index_op (idx, resize_ok);
+  return tmp.index_op (idx, resize_ok);
 }
 
 double
--- a/libinterp/octave-value/ov-intx.h	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov-intx.h	Thu Jul 30 16:16:04 2020 -0400
@@ -427,7 +427,7 @@
     (new OCTAVE_VALUE_INT_MATRIX_T
      (OCTAVE_VALUE_INT_NDARRAY_EXTRACTOR_FUNCTION ()));
 
-    return tmp.do_index_op (idx, resize_ok);
+    return tmp.index_op (idx, resize_ok);
   }
 
   bool OCTAVE_TYPE_PREDICATE_FUNCTION (void) const { return true; }
--- a/libinterp/octave-value/ov-lazy-idx.h	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov-lazy-idx.h	Thu Jul 30 16:16:04 2020 -0400
@@ -93,7 +93,7 @@
 
   octave_value do_index_op (const octave_value_list& idx,
                             bool resize_ok = false)
-  { return make_value ().do_index_op (idx, resize_ok); }
+  { return make_value ().index_op (idx, resize_ok); }
 
   dim_vector dims (void) const { return index.orig_dimensions (); }
 
--- a/libinterp/octave-value/ov-magic-int.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov-magic-int.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -81,7 +81,7 @@
 {
   octave_value tmp (double_value ());
 
-  return tmp.do_index_op (idx, resize_ok);
+  return tmp.index_op (idx, resize_ok);
 }
 
 template <typename T>
--- a/libinterp/octave-value/ov-perm.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov-perm.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -128,7 +128,7 @@
       if (nidx == 2 && ! resize_ok && idx0.is_scalar () && idx1.is_scalar ())
         retval = matrix.checkelem (idx0(0), idx1(0));
       else
-        retval = to_dense ().do_index_op (idx, resize_ok);
+        retval = to_dense ().index_op (idx, resize_ok);
     }
 
   return retval;
--- a/libinterp/octave-value/ov-range.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov-range.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -165,7 +165,7 @@
     {
       octave_value tmp (new octave_matrix (range.matrix_value ()));
 
-      return tmp.do_index_op (idx, resize_ok);
+      return tmp.index_op (idx, resize_ok);
     }
 }
 
--- a/libinterp/octave-value/ov-scalar.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov-scalar.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -98,7 +98,7 @@
 
   octave_value tmp (new octave_matrix (matrix_value ()));
 
-  return tmp.do_index_op (idx, resize_ok);
+  return tmp.index_op (idx, resize_ok);
 }
 
 octave_value
--- a/libinterp/octave-value/ov.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -1510,7 +1510,7 @@
 
       binary_op binop = op_eq_to_binary_op (op);
 
-      t_rhs = do_binary_op (binop, t, rhs);
+      t_rhs = octave::binary_op (binop, t, rhs);
     }
 
   *this = subsasgn (type, idx, t_rhs);
@@ -1542,7 +1542,7 @@
 
       if (f)
         {
-          f (*rep, octave_value_list (), *rhs.rep);
+          f (*rep, octave_value_list (), rhs.get_rep ());
           // Usually unnecessary, but may be needed (complex arrays).
           maybe_mutate ();
         }
@@ -1551,7 +1551,7 @@
 
           binary_op binop = op_eq_to_binary_op (op);
 
-          octave_value t = do_binary_op (binop, *this, rhs);
+          octave_value t = octave::binary_op (binop, *this, rhs);
 
           operator = (t);
         }
@@ -1613,7 +1613,7 @@
 
   if (rows () == test.rows () && columns () == test.columns ())
     {
-      octave_value tmp = do_binary_op (octave_value::op_eq, *this, test);
+      octave_value tmp = octave::binary_op (octave_value::op_eq, *this, test);
 
       // Empty array also means a match.
       if (tmp.is_defined ())
@@ -2173,449 +2173,6 @@
   return rep->write (os, block_size, output_type, skip, flt_fmt);
 }
 
-OCTAVE_NORETURN static void
-err_binary_op (const std::string& on, const std::string& tn1,
-               const std::string& tn2)
-{
-  error ("binary operator '%s' not implemented for '%s' by '%s' operations",
-         on.c_str (), tn1.c_str (), tn2.c_str ());
-}
-
-OCTAVE_NORETURN static void
-err_binary_op_conv (const std::string& on)
-{
-  error ("type conversion failed for binary operator '%s'", on.c_str ());
-}
-
-octave_value
-do_binary_op (octave::type_info& ti, octave_value::binary_op op,
-              const octave_value& v1, const octave_value& v2)
-{
-  octave_value retval;
-
-  int t1 = v1.type_id ();
-  int t2 = v2.type_id ();
-
-  if (t1 == octave_class::static_type_id ()
-      || t2 == octave_class::static_type_id ()
-      || t1 == octave_classdef::static_type_id ()
-      || t2 == octave_classdef::static_type_id ())
-    {
-      octave::type_info::binary_class_op_fcn f
-        = ti.lookup_binary_class_op (op);
-
-      if (! f)
-        err_binary_op (octave_value::binary_op_as_string (op),
-                       v1.class_name (), v2.class_name ());
-
-      retval = f (v1, v2);
-    }
-  else
-    {
-      // FIXME: we need to handle overloading operators for built-in
-      // classes (double, char, int8, etc.)
-
-      octave::type_info::binary_op_fcn f
-        = ti.lookup_binary_op (op, t1, t2);
-
-      if (f)
-        retval = f (*v1.rep, *v2.rep);
-      else
-        {
-          octave_value tv1;
-          octave_base_value::type_conv_info cf1
-            = v1.numeric_conversion_function ();
-
-          octave_value tv2;
-          octave_base_value::type_conv_info cf2
-            = v2.numeric_conversion_function ();
-
-          // Try biased (one-sided) conversions first.
-          if (cf2.type_id () >= 0
-              && ti.lookup_binary_op (op, t1, cf2.type_id ()))
-            cf1 = nullptr;
-          else if (cf1.type_id () >= 0
-                   && ti.lookup_binary_op (op, cf1.type_id (), t2))
-            cf2 = nullptr;
-
-          if (cf1)
-            {
-              octave_base_value *tmp = cf1 (*v1.rep);
-
-              if (! tmp)
-                err_binary_op_conv (octave_value::binary_op_as_string (op));
-
-              tv1 = octave_value (tmp);
-              t1 = tv1.type_id ();
-            }
-          else
-            tv1 = v1;
-
-          if (cf2)
-            {
-              octave_base_value *tmp = cf2 (*v2.rep);
-
-              if (! tmp)
-                err_binary_op_conv (octave_value::binary_op_as_string (op));
-
-              tv2 = octave_value (tmp);
-              t2 = tv2.type_id ();
-            }
-          else
-            tv2 = v2;
-
-          if (cf1 || cf2)
-            {
-              retval = do_binary_op (op, tv1, tv2);
-            }
-          else
-            {
-              //demote double -> single and try again
-              cf1 = tv1.numeric_demotion_function ();
-
-              cf2 = tv2.numeric_demotion_function ();
-
-              // Try biased (one-sided) conversions first.
-              if (cf2.type_id () >= 0
-                  && ti.lookup_binary_op (op, t1, cf2.type_id ()))
-                cf1 = nullptr;
-              else if (cf1.type_id () >= 0
-                       && ti.lookup_binary_op (op, cf1.type_id (), t2))
-                cf2 = nullptr;
-
-              if (cf1)
-                {
-                  octave_base_value *tmp = cf1 (*tv1.rep);
-
-                  if (! tmp)
-                    err_binary_op_conv (octave_value::binary_op_as_string (op));
-
-                  tv1 = octave_value (tmp);
-                  t1 = tv1.type_id ();
-                }
-
-              if (cf2)
-                {
-                  octave_base_value *tmp = cf2 (*tv2.rep);
-
-                  if (! tmp)
-                    err_binary_op_conv (octave_value::binary_op_as_string (op));
-
-                  tv2 = octave_value (tmp);
-                  t2 = tv2.type_id ();
-                }
-
-              if (! cf1 && ! cf2)
-                err_binary_op (octave_value::binary_op_as_string (op),
-                               v1.type_name (), v2.type_name ());
-
-              f = ti.lookup_binary_op (op, t1, t2);
-
-              if (! f)
-                err_binary_op (octave_value::binary_op_as_string (op),
-                               v1.type_name (), v2.type_name ());
-
-              retval = f (*tv1.rep, *tv2.rep);
-            }
-        }
-    }
-
-  return retval;
-}
-
-octave_value
-do_binary_op (octave_value::binary_op op,
-              const octave_value& v1, const octave_value& v2)
-{
-  octave::type_info& ti = octave::__get_type_info__ ("do_binary_op");
-
-  return do_binary_op (ti, op, v1, v2);
-}
-
-static octave_value
-decompose_binary_op (octave::type_info& ti,
-                     octave_value::compound_binary_op op,
-                     const octave_value& v1, const octave_value& v2)
-{
-  switch (op)
-    {
-    case octave_value::op_trans_mul:
-      return do_binary_op (octave_value::op_mul,
-                           do_unary_op (octave_value::op_transpose, v1), v2);
-
-    case octave_value::op_mul_trans:
-      return do_binary_op (ti, octave_value::op_mul,
-                           v1, do_unary_op (octave_value::op_transpose, v2));
-
-    case octave_value::op_herm_mul:
-      return do_binary_op (ti, octave_value::op_mul,
-                           do_unary_op (octave_value::op_hermitian, v1), v2);
-
-    case octave_value::op_mul_herm:
-      return do_binary_op (ti, octave_value::op_mul,
-                           v1, do_unary_op (octave_value::op_hermitian, v2));
-
-    case octave_value::op_trans_ldiv:
-      return do_binary_op (ti, octave_value::op_ldiv,
-                           do_unary_op (octave_value::op_transpose, v1), v2);
-
-    case octave_value::op_herm_ldiv:
-      return do_binary_op (ti, octave_value::op_ldiv,
-                           do_unary_op (octave_value::op_hermitian, v1), v2);
-
-    case octave_value::op_el_not_and:
-      return do_binary_op (ti, octave_value::op_el_and,
-                           do_unary_op (octave_value::op_not, v1), v2);
-
-    case octave_value::op_el_not_or:
-      return do_binary_op (ti, octave_value::op_el_or,
-                           do_unary_op (octave_value::op_not, v1), v2);
-
-    case octave_value::op_el_and_not:
-      return do_binary_op (ti, octave_value::op_el_and,
-                           v1, do_unary_op (octave_value::op_not, v2));
-
-    case octave_value::op_el_or_not:
-      return do_binary_op (ti, octave_value::op_el_or,
-                           v1, do_unary_op (octave_value::op_not, v2));
-
-    default:
-      error ("invalid compound operator");
-    }
-}
-
-octave_value
-do_binary_op (octave::type_info& ti, octave_value::compound_binary_op op,
-              const octave_value& v1, const octave_value& v2)
-{
-  octave_value retval;
-
-  int t1 = v1.type_id ();
-  int t2 = v2.type_id ();
-
-  if (t1 == octave_class::static_type_id ()
-      || t2 == octave_class::static_type_id ()
-      || t1 == octave_classdef::static_type_id ()
-      || t2 == octave_classdef::static_type_id ())
-    {
-      octave::type_info::binary_class_op_fcn f = ti.lookup_binary_class_op (op);
-
-      if (f)
-        retval = f (v1, v2);
-      else
-        retval = decompose_binary_op (ti, op, v1, v2);
-    }
-  else
-    {
-      octave::type_info::binary_op_fcn f = ti.lookup_binary_op (op, t1, t2);
-
-      if (f)
-        retval = f (*v1.rep, *v2.rep);
-      else
-        retval = decompose_binary_op (ti, op, v1, v2);
-    }
-
-  return retval;
-}
-
-octave_value
-do_binary_op (octave_value::compound_binary_op op,
-              const octave_value& v1, const octave_value& v2)
-{
-  octave::type_info& ti = octave::__get_type_info__ ("do_binary_op");
-
-  return do_binary_op (ti, op, v1, v2);
-}
-
-OCTAVE_NORETURN static void
-err_cat_op (const std::string& tn1, const std::string& tn2)
-{
-  error ("concatenation operator not implemented for '%s' by '%s' operations",
-         tn1.c_str (), tn2.c_str ());
-}
-
-OCTAVE_NORETURN static void
-err_cat_op_conv (void)
-{
-  error ("type conversion failed for concatenation operator");
-}
-
-octave_value
-do_cat_op (octave::type_info& ti, const octave_value& v1,
-           const octave_value& v2, const Array<octave_idx_type>& ra_idx)
-{
-  octave_value retval;
-
-  // Can't rapid return for concatenation with an empty object here as
-  // something like cat(1,[],single([]) must return the correct type.
-
-  int t1 = v1.type_id ();
-  int t2 = v2.type_id ();
-
-  octave::type_info::cat_op_fcn f = ti.lookup_cat_op (t1, t2);
-
-  if (f)
-    retval = f (*v1.rep, *v2.rep, ra_idx);
-  else
-    {
-      octave_value tv1;
-      octave_base_value::type_conv_info cf1 = v1.numeric_conversion_function ();
-
-      octave_value tv2;
-      octave_base_value::type_conv_info cf2 = v2.numeric_conversion_function ();
-
-      // Try biased (one-sided) conversions first.
-      if (cf2.type_id () >= 0 && ti.lookup_cat_op (t1, cf2.type_id ()))
-        cf1 = nullptr;
-      else if (cf1.type_id () >= 0 && ti.lookup_cat_op (cf1.type_id (), t2))
-        cf2 = nullptr;
-
-      if (cf1)
-        {
-          octave_base_value *tmp = cf1 (*v1.rep);
-
-          if (! tmp)
-            err_cat_op_conv ();
-
-          tv1 = octave_value (tmp);
-          t1 = tv1.type_id ();
-        }
-      else
-        tv1 = v1;
-
-      if (cf2)
-        {
-          octave_base_value *tmp = cf2 (*v2.rep);
-
-          if (! tmp)
-            err_cat_op_conv ();
-
-          tv2 = octave_value (tmp);
-          t2 = tv2.type_id ();
-        }
-      else
-        tv2 = v2;
-
-      if (! cf1 && ! cf2)
-        err_cat_op (v1.type_name (), v2.type_name ());
-
-      retval = do_cat_op (ti, tv1, tv2, ra_idx);
-    }
-
-  return retval;
-}
-
-octave_value
-do_cat_op (const octave_value& v1, const octave_value& v2,
-           const Array<octave_idx_type>& ra_idx)
-{
-  octave::type_info& ti = octave::__get_type_info__ ("do_cat_op");
-
-  return do_cat_op (ti, v1, v2, ra_idx);
-}
-
-octave_value
-do_colon_op (const octave_value& base, const octave_value& increment,
-             const octave_value& limit, bool is_for_cmd_expr)
-{
-  octave_value retval;
-
-  if (base.isobject () || increment.isobject () || limit.isobject ())
-    {
-      octave_value_list tmp1;
-
-      if (increment.is_defined ())
-        {
-          tmp1(2) = limit;
-          tmp1(1) = increment;
-          tmp1(0) = base;
-        }
-      else
-        {
-          tmp1(1) = limit;
-          tmp1(0) = base;
-        }
-
-      octave::interpreter& interp = octave::__get_interpreter__ ("do_colon_op");
-
-      octave::symbol_table& symtab = interp.get_symbol_table ();
-
-      octave_value fcn = symtab.find_function ("colon", tmp1);
-
-      if (fcn.is_defined ())
-        {
-          octave_value_list tmp2 = interp.feval (fcn, tmp1, 1);
-
-          return tmp2 (0);
-        }
-    }
-
-  bool result_is_str = (base.is_string () && limit.is_string ());
-  bool dq_str = (base.is_dq_string () || limit.is_dq_string ());
-
-  if (base.numel () > 1 || limit.numel () > 1
-      || (increment.is_defined () && increment.numel () > 1))
-    warning_with_id ("Octave:colon-nonscalar-argument",
-                     "colon arguments should be scalars");
-
-  if (base.iscomplex () || limit.iscomplex ()
-      || (increment.is_defined () && increment.iscomplex ()))
-    warning_with_id ("Octave:colon-complex-argument",
-                     "imaginary part of complex colon arguments is ignored");
-
-  Matrix m_base, m_limit, m_increment;
-
-  try
-    {
-      m_base = base.matrix_value (true);
-    }
-  catch (octave::execution_exception& e)
-    {
-      error (e, "invalid base value in colon expression");
-    }
-
-  try
-    {
-      m_limit = limit.matrix_value (true);
-    }
-  catch (octave::execution_exception& e)
-    {
-      error (e, "invalid limit value in colon expression");
-    }
-
-  try
-    {
-      m_increment = (increment.is_defined ()
-                     ? increment.matrix_value (true)
-                     : Matrix (1, 1, 1.0));
-    }
-  catch (octave::execution_exception& e)
-    {
-      error (e, "invalid increment value in colon expression");
-    }
-
-  bool base_empty = m_base.isempty ();
-  bool limit_empty = m_limit.isempty ();
-  bool increment_empty = m_increment.isempty ();
-
-  if (base_empty || limit_empty || increment_empty)
-    retval = Range ();
-  else
-    {
-      Range r (m_base(0), m_limit(0), m_increment(0));
-
-      // For compatibility with Matlab, don't allow the range used in
-      // a FOR loop expression to be converted to a Matrix.
-
-      retval = octave_value (r, is_for_cmd_expr);
-
-      if (result_is_str)
-        retval = (retval.convert_to_str (false, true, dq_str ? '"' : '\''));
-    }
-
-  return retval;
-}
-
 void
 octave_value::print_info (std::ostream& os, const std::string& prefix) const
 {
@@ -2696,77 +2253,6 @@
 }
 
 OCTAVE_NORETURN static void
-err_unary_op (const std::string& on, const std::string& tn)
-{
-  error ("unary operator '%s' not implemented for '%s' operands",
-         on.c_str (), tn.c_str ());
-}
-
-OCTAVE_NORETURN static void
-err_unary_op_conv (const std::string& on)
-{
-  error ("type conversion failed for unary operator '%s'", on.c_str ());
-}
-
-octave_value
-do_unary_op (octave::type_info& ti, octave_value::unary_op op,
-             const octave_value& v)
-{
-  octave_value retval;
-
-  int t = v.type_id ();
-
-  if (t == octave_class::static_type_id ()
-      || t == octave_classdef::static_type_id ())
-    {
-      octave::type_info::unary_class_op_fcn f = ti.lookup_unary_class_op (op);
-
-      if (! f)
-        err_unary_op (octave_value::unary_op_as_string (op), v.class_name ());
-
-      retval = f (v);
-    }
-  else
-    {
-      // FIXME: we need to handle overloading operators for built-in
-      // classes (double, char, int8, etc.)
-
-      octave::type_info::unary_op_fcn f = ti.lookup_unary_op (op, t);
-
-      if (f)
-        retval = f (*v.rep);
-      else
-        {
-          octave_value tv;
-          octave_base_value::type_conv_fcn cf
-            = v.numeric_conversion_function ();
-
-          if (! cf)
-            err_unary_op (octave_value::unary_op_as_string (op),
-                          v.type_name ());
-
-          octave_base_value *tmp = cf (*v.rep);
-
-          if (! tmp)
-            err_unary_op_conv (octave_value::unary_op_as_string (op));
-
-          tv = octave_value (tmp);
-          retval = do_unary_op (op, tv);
-        }
-    }
-
-  return retval;
-}
-
-octave_value
-do_unary_op (octave_value::unary_op op, const octave_value& v)
-{
-  octave::type_info& ti = octave::__get_type_info__ ("do_unary_op");
-
-  return do_unary_op (ti, op, v);
-}
-
-OCTAVE_NORETURN static void
 err_unary_op_conversion_failed (const std::string& op,
                                 const std::string& tn)
 {
@@ -2774,8 +2260,15 @@
          op.c_str (), tn.c_str ());
 }
 
+OCTAVE_NORETURN static void
+err_unary_op (const std::string& on, const std::string& tn)
+{
+  error ("unary operator '%s' not implemented for '%s' operands",
+         on.c_str (), tn.c_str ());
+}
+
 octave_value&
-octave_value::do_non_const_unary_op (unary_op op)
+octave_value::non_const_unary_op (unary_op op)
 {
   if (op == op_incr || op == op_decr)
     {
@@ -2793,8 +2286,7 @@
       // Genuine.
       int t = type_id ();
 
-      octave::type_info& ti
-        = octave::__get_type_info__ ("do_non_const_unary_op");
+      octave::type_info& ti = octave::__get_type_info__ ("non_const_unary_op");
 
       octave::type_info::non_const_unary_op_fcn f
         = ti.lookup_non_const_unary_op (op, t);
@@ -2858,7 +2350,7 @@
       if (rep->count == 1)
         {
           octave::type_info& ti
-            = octave::__get_type_info__ ("do_non_const_unary_op");
+            = octave::__get_type_info__ ("non_const_unary_op");
 
           f = ti.lookup_non_const_unary_op (op, t);
         }
@@ -2866,18 +2358,18 @@
       if (f)
         f (*rep);
       else
-        *this = do_unary_op (op, *this);
+        *this = octave::unary_op (op, *this);
     }
 
   return *this;
 }
 
 octave_value&
-octave_value::do_non_const_unary_op (unary_op op, const std::string& type,
-                                     const std::list<octave_value_list>& idx)
+octave_value::non_const_unary_op (unary_op op, const std::string& type,
+                                  const std::list<octave_value_list>& idx)
 {
   if (idx.empty ())
-    do_non_const_unary_op (op);
+    non_const_unary_op (op);
   else
     {
       // FIXME: only do the following stuff if we can't find a
@@ -2987,6 +2479,514 @@
     return octave_value (rhs.empty_clone ());
 }
 
+namespace octave
+{
+  OCTAVE_NORETURN static void
+  err_binary_op (const std::string& on, const std::string& tn1,
+                 const std::string& tn2)
+  {
+    error ("binary operator '%s' not implemented for '%s' by '%s' operations",
+           on.c_str (), tn1.c_str (), tn2.c_str ());
+  }
+
+  OCTAVE_NORETURN static void
+  err_binary_op_conv (const std::string& on)
+  {
+    error ("type conversion failed for binary operator '%s'", on.c_str ());
+  }
+
+  octave_value
+  binary_op (type_info& ti, octave_value::binary_op op,
+             const octave_value& v1, const octave_value& v2)
+  {
+    octave_value retval;
+
+    int t1 = v1.type_id ();
+    int t2 = v2.type_id ();
+
+    if (t1 == octave_class::static_type_id ()
+        || t2 == octave_class::static_type_id ()
+        || t1 == octave_classdef::static_type_id ()
+        || t2 == octave_classdef::static_type_id ())
+      {
+        type_info::binary_class_op_fcn f = ti.lookup_binary_class_op (op);
+
+        if (! f)
+          err_binary_op (octave_value::binary_op_as_string (op),
+                         v1.class_name (), v2.class_name ());
+
+        retval = f (v1, v2);
+      }
+    else
+      {
+        // FIXME: we need to handle overloading operators for built-in
+        // classes (double, char, int8, etc.)
+
+        type_info::binary_op_fcn f
+          = ti.lookup_binary_op (op, t1, t2);
+
+        if (f)
+          retval = f (v1.get_rep (), v2.get_rep ());
+        else
+          {
+            octave_value tv1;
+            octave_base_value::type_conv_info cf1
+              = v1.numeric_conversion_function ();
+
+            octave_value tv2;
+            octave_base_value::type_conv_info cf2
+              = v2.numeric_conversion_function ();
+
+            // Try biased (one-sided) conversions first.
+            if (cf2.type_id () >= 0
+                && ti.lookup_binary_op (op, t1, cf2.type_id ()))
+              cf1 = nullptr;
+            else if (cf1.type_id () >= 0
+                     && ti.lookup_binary_op (op, cf1.type_id (), t2))
+              cf2 = nullptr;
+
+            if (cf1)
+              {
+                octave_base_value *tmp = cf1 (v1.get_rep ());
+
+                if (! tmp)
+                  err_binary_op_conv (octave_value::binary_op_as_string (op));
+
+                tv1 = octave_value (tmp);
+                t1 = tv1.type_id ();
+              }
+            else
+              tv1 = v1;
+
+            if (cf2)
+              {
+                octave_base_value *tmp = cf2 (v2.get_rep ());
+
+                if (! tmp)
+                  err_binary_op_conv (octave_value::binary_op_as_string (op));
+
+                tv2 = octave_value (tmp);
+                t2 = tv2.type_id ();
+              }
+            else
+              tv2 = v2;
+
+            if (cf1 || cf2)
+              {
+                retval = binary_op (op, tv1, tv2);
+              }
+            else
+              {
+                //demote double -> single and try again
+                cf1 = tv1.numeric_demotion_function ();
+
+                cf2 = tv2.numeric_demotion_function ();
+
+                // Try biased (one-sided) conversions first.
+                if (cf2.type_id () >= 0
+                    && ti.lookup_binary_op (op, t1, cf2.type_id ()))
+                  cf1 = nullptr;
+                else if (cf1.type_id () >= 0
+                         && ti.lookup_binary_op (op, cf1.type_id (), t2))
+                  cf2 = nullptr;
+
+                if (cf1)
+                  {
+                    octave_base_value *tmp = cf1 (tv1.get_rep ());
+
+                    if (! tmp)
+                      err_binary_op_conv (octave_value::binary_op_as_string (op));
+
+                    tv1 = octave_value (tmp);
+                    t1 = tv1.type_id ();
+                  }
+
+                if (cf2)
+                  {
+                    octave_base_value *tmp = cf2 (tv2.get_rep ());
+
+                    if (! tmp)
+                      err_binary_op_conv (octave_value::binary_op_as_string (op));
+
+                    tv2 = octave_value (tmp);
+                    t2 = tv2.type_id ();
+                  }
+
+                if (! cf1 && ! cf2)
+                  err_binary_op (octave_value::binary_op_as_string (op),
+                                 v1.type_name (), v2.type_name ());
+
+                f = ti.lookup_binary_op (op, t1, t2);
+
+                if (! f)
+                  err_binary_op (octave_value::binary_op_as_string (op),
+                                 v1.type_name (), v2.type_name ());
+
+                retval = f (tv1.get_rep (), tv2.get_rep ());
+              }
+          }
+      }
+
+    return retval;
+  }
+
+  octave_value
+  binary_op (octave_value::binary_op op, const octave_value& v1,
+             const octave_value& v2)
+  {
+    type_info& ti = __get_type_info__ ("binary_op");
+
+    return binary_op (ti, op, v1, v2);
+  }
+
+  static octave_value
+  decompose_binary_op (type_info& ti, octave_value::compound_binary_op op,
+                       const octave_value& v1, const octave_value& v2)
+  {
+    switch (op)
+      {
+      case octave_value::op_trans_mul:
+        return binary_op (octave_value::op_mul,
+                          unary_op (octave_value::op_transpose, v1), v2);
+
+      case octave_value::op_mul_trans:
+        return binary_op (ti, octave_value::op_mul,
+                          v1, unary_op (octave_value::op_transpose, v2));
+
+      case octave_value::op_herm_mul:
+        return binary_op (ti, octave_value::op_mul,
+                          unary_op (octave_value::op_hermitian, v1), v2);
+
+      case octave_value::op_mul_herm:
+        return binary_op (ti, octave_value::op_mul,
+                          v1, unary_op (octave_value::op_hermitian, v2));
+
+      case octave_value::op_trans_ldiv:
+        return binary_op (ti, octave_value::op_ldiv,
+                          unary_op (octave_value::op_transpose, v1), v2);
+
+      case octave_value::op_herm_ldiv:
+        return binary_op (ti, octave_value::op_ldiv,
+                          unary_op (octave_value::op_hermitian, v1), v2);
+
+      case octave_value::op_el_not_and:
+        return binary_op (ti, octave_value::op_el_and,
+                          unary_op (octave_value::op_not, v1), v2);
+
+      case octave_value::op_el_not_or:
+        return binary_op (ti, octave_value::op_el_or,
+                          unary_op (octave_value::op_not, v1), v2);
+
+      case octave_value::op_el_and_not:
+        return binary_op (ti, octave_value::op_el_and,
+                          v1, unary_op (octave_value::op_not, v2));
+
+      case octave_value::op_el_or_not:
+        return binary_op (ti, octave_value::op_el_or,
+                          v1, unary_op (octave_value::op_not, v2));
+
+      default:
+        error ("invalid compound operator");
+      }
+  }
+
+  octave_value
+  binary_op (type_info& ti, octave_value::compound_binary_op op,
+             const octave_value& v1, const octave_value& v2)
+  {
+    octave_value retval;
+
+    int t1 = v1.type_id ();
+    int t2 = v2.type_id ();
+
+    if (t1 == octave_class::static_type_id ()
+        || t2 == octave_class::static_type_id ()
+        || t1 == octave_classdef::static_type_id ()
+        || t2 == octave_classdef::static_type_id ())
+      {
+        type_info::binary_class_op_fcn f = ti.lookup_binary_class_op (op);
+
+        if (f)
+          retval = f (v1, v2);
+        else
+          retval = decompose_binary_op (ti, op, v1, v2);
+      }
+    else
+      {
+        type_info::binary_op_fcn f = ti.lookup_binary_op (op, t1, t2);
+
+        if (f)
+          retval = f (v1.get_rep (), v2.get_rep ());
+        else
+          retval = decompose_binary_op (ti, op, v1, v2);
+      }
+
+    return retval;
+  }
+
+  octave_value
+  binary_op (octave_value::compound_binary_op op,
+             const octave_value& v1, const octave_value& v2)
+  {
+    type_info& ti = __get_type_info__ ("binary_op");
+
+    return binary_op (ti, op, v1, v2);
+  }
+
+  OCTAVE_NORETURN static void
+  err_cat_op (const std::string& tn1, const std::string& tn2)
+  {
+    error ("concatenation operator not implemented for '%s' by '%s' operations",
+           tn1.c_str (), tn2.c_str ());
+  }
+
+  OCTAVE_NORETURN static void
+  err_cat_op_conv (void)
+  {
+    error ("type conversion failed for concatenation operator");
+  }
+
+  octave_value
+  cat_op (type_info& ti, const octave_value& v1,
+          const octave_value& v2, const Array<octave_idx_type>& ra_idx)
+  {
+    octave_value retval;
+
+    // Can't rapid return for concatenation with an empty object here as
+    // something like cat(1,[],single([]) must return the correct type.
+
+    int t1 = v1.type_id ();
+    int t2 = v2.type_id ();
+
+    type_info::cat_op_fcn f = ti.lookup_cat_op (t1, t2);
+
+    if (f)
+      retval = f (v1.get_rep (), v2.get_rep (), ra_idx);
+    else
+      {
+        octave_value tv1;
+        octave_base_value::type_conv_info cf1 = v1.numeric_conversion_function ();
+
+        octave_value tv2;
+        octave_base_value::type_conv_info cf2 = v2.numeric_conversion_function ();
+
+        // Try biased (one-sided) conversions first.
+        if (cf2.type_id () >= 0 && ti.lookup_cat_op (t1, cf2.type_id ()))
+          cf1 = nullptr;
+        else if (cf1.type_id () >= 0 && ti.lookup_cat_op (cf1.type_id (), t2))
+          cf2 = nullptr;
+
+        if (cf1)
+          {
+            octave_base_value *tmp = cf1 (v1.get_rep ());
+
+            if (! tmp)
+              err_cat_op_conv ();
+
+            tv1 = octave_value (tmp);
+            t1 = tv1.type_id ();
+          }
+        else
+          tv1 = v1;
+
+        if (cf2)
+          {
+            octave_base_value *tmp = cf2 (v2.get_rep ());
+
+            if (! tmp)
+              err_cat_op_conv ();
+
+            tv2 = octave_value (tmp);
+            t2 = tv2.type_id ();
+          }
+        else
+          tv2 = v2;
+
+        if (! cf1 && ! cf2)
+          err_cat_op (v1.type_name (), v2.type_name ());
+
+        retval = cat_op (ti, tv1, tv2, ra_idx);
+      }
+
+    return retval;
+  }
+
+  octave_value
+  cat_op (const octave_value& v1, const octave_value& v2,
+          const Array<octave_idx_type>& ra_idx)
+  {
+    type_info& ti = __get_type_info__ ("cat_op");
+
+    return cat_op (ti, v1, v2, ra_idx);
+  }
+
+  octave_value
+  colon_op (const octave_value& base, const octave_value& increment,
+            const octave_value& limit, bool is_for_cmd_expr)
+  {
+    octave_value retval;
+
+    if (base.isobject () || increment.isobject () || limit.isobject ())
+      {
+        octave_value_list tmp1;
+
+        if (increment.is_defined ())
+          {
+            tmp1(2) = limit;
+            tmp1(1) = increment;
+            tmp1(0) = base;
+          }
+        else
+          {
+            tmp1(1) = limit;
+            tmp1(0) = base;
+          }
+
+        interpreter& interp = __get_interpreter__ ("colon_op");
+
+        symbol_table& symtab = interp.get_symbol_table ();
+
+        octave_value fcn = symtab.find_function ("colon", tmp1);
+
+        if (fcn.is_defined ())
+          {
+            octave_value_list tmp2 = interp.feval (fcn, tmp1, 1);
+
+            return tmp2 (0);
+          }
+      }
+
+    bool result_is_str = (base.is_string () && limit.is_string ());
+    bool dq_str = (base.is_dq_string () || limit.is_dq_string ());
+
+    if (base.numel () > 1 || limit.numel () > 1
+        || (increment.is_defined () && increment.numel () > 1))
+      warning_with_id ("Octave:colon-nonscalar-argument",
+                       "colon arguments should be scalars");
+
+    if (base.iscomplex () || limit.iscomplex ()
+        || (increment.is_defined () && increment.iscomplex ()))
+      warning_with_id ("Octave:colon-complex-argument",
+                       "imaginary part of complex colon arguments is ignored");
+
+    Matrix m_base, m_limit, m_increment;
+
+    try
+      {
+        m_base = base.matrix_value (true);
+      }
+    catch (execution_exception& e)
+      {
+        error (e, "invalid base value in colon expression");
+      }
+
+    try
+      {
+        m_limit = limit.matrix_value (true);
+      }
+    catch (execution_exception& e)
+      {
+        error (e, "invalid limit value in colon expression");
+      }
+
+    try
+      {
+        m_increment = (increment.is_defined ()
+                       ? increment.matrix_value (true)
+                       : Matrix (1, 1, 1.0));
+      }
+    catch (execution_exception& e)
+      {
+        error (e, "invalid increment value in colon expression");
+      }
+
+    bool base_empty = m_base.isempty ();
+    bool limit_empty = m_limit.isempty ();
+    bool increment_empty = m_increment.isempty ();
+
+    if (base_empty || limit_empty || increment_empty)
+      retval = Range ();
+    else
+      {
+        Range r (m_base(0), m_limit(0), m_increment(0));
+
+        // For compatibility with Matlab, don't allow the range used in
+        // a FOR loop expression to be converted to a Matrix.
+
+        retval = octave_value (r, is_for_cmd_expr);
+
+        if (result_is_str)
+          retval = (retval.convert_to_str (false, true, dq_str ? '"' : '\''));
+      }
+
+    return retval;
+  }
+
+  OCTAVE_NORETURN static void
+  err_unary_op_conv (const std::string& on)
+  {
+    error ("type conversion failed for unary operator '%s'", on.c_str ());
+  }
+
+  octave_value
+  unary_op (type_info& ti, octave_value::unary_op op,
+            const octave_value& v)
+  {
+    octave_value retval;
+
+    int t = v.type_id ();
+
+    if (t == octave_class::static_type_id ()
+        || t == octave_classdef::static_type_id ())
+      {
+        type_info::unary_class_op_fcn f = ti.lookup_unary_class_op (op);
+
+        if (! f)
+          err_unary_op (octave_value::unary_op_as_string (op), v.class_name ());
+
+        retval = f (v);
+      }
+    else
+      {
+        // FIXME: we need to handle overloading operators for built-in
+        // classes (double, char, int8, etc.)
+
+        type_info::unary_op_fcn f = ti.lookup_unary_op (op, t);
+
+        if (f)
+          retval = f (v.get_rep ());
+        else
+          {
+            octave_value tv;
+            octave_base_value::type_conv_fcn cf
+              = v.numeric_conversion_function ();
+
+            if (! cf)
+              err_unary_op (octave_value::unary_op_as_string (op),
+                            v.type_name ());
+
+            octave_base_value *tmp = cf (v.get_rep ());
+
+            if (! tmp)
+              err_unary_op_conv (octave_value::unary_op_as_string (op));
+
+            tv = octave_value (tmp);
+            retval = unary_op (op, tv);
+          }
+      }
+
+    return retval;
+  }
+
+  octave_value
+  unary_op (octave_value::unary_op op, const octave_value& v)
+  {
+    type_info& ti = __get_type_info__ ("unary_op");
+
+    return unary_op (ti, op, v);
+  }
+}
+
 void
 install_types (octave::type_info& ti)
 {
--- a/libinterp/octave-value/ov.h	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/octave-value/ov.h	Thu Jul 30 16:16:04 2020 -0400
@@ -64,17 +64,6 @@
 #include "oct-stream.h"
 #include "ov-base.h"
 
-// Forward declarations of friend functions that have default arguments.
-
-OCTINTERP_API octave_value do_colon_op (const octave_value& base,
-                                        const octave_value& limit,
-                                        bool is_for_cmd_expr = false);
-
-OCTINTERP_API octave_value do_colon_op (const octave_value& base,
-                                        const octave_value& increment,
-                                        const octave_value& limit,
-                                        bool is_for_cmd_expr = false);
-
 class
 OCTINTERP_API
 octave_value
@@ -474,9 +463,17 @@
                              std::list<octave_value_list>& idx,
                              size_t skip = 1);
 
+  octave_value index_op (const octave_value_list& idx, bool resize_ok = false)
+  {
+    return rep->do_index_op (idx, resize_ok);
+  }
+
+  OCTAVE_DEPRECATED (7, "use 'octave_value::index_op' instead")
   octave_value do_index_op (const octave_value_list& idx,
                             bool resize_ok = false)
-  { return rep->do_index_op (idx, resize_ok); }
+  {
+    return index_op (idx, resize_ok);
+  }
 
   octave_value subsasgn (const std::string& type,
                          const std::list<octave_value_list>& idx,
@@ -1260,39 +1257,27 @@
 
   std::string class_name (void) const { return rep->class_name (); }
 
-  // Unary and binary operations.
-
-  friend OCTINTERP_API octave_value
-  do_unary_op (octave::type_info& ti, unary_op op, const octave_value& a);
-
-  octave_value& do_non_const_unary_op (unary_op op);
-
-  octave_value& do_non_const_unary_op (unary_op op, const std::string& type,
-                                       const std::list<octave_value_list>& idx);
-
-  friend OCTINTERP_API octave_value
-  do_binary_op (octave::type_info& ti, binary_op op,
-                const octave_value& a, const octave_value& b);
+  // Unary operations that are member functions.  There are also some
+  // non-member functions for unary and binary operations declared
+  // below, outside of the octave_value class declaration.
 
-  friend OCTINTERP_API octave_value
-  do_binary_op (octave::type_info& ti, compound_binary_op op,
-                const octave_value& a, const octave_value& b);
+  octave_value& non_const_unary_op (unary_op op);
 
-  friend OCTINTERP_API octave_value
-  do_cat_op (octave::type_info& ti, const octave_value& a,
-             const octave_value& b, const Array<octave_idx_type>& ra_idx);
-
-  friend OCTINTERP_API octave_value do_colon_op (const octave_value& base,
-                                                 const octave_value& limit,
-                                                 bool is_for_cmd_expr)
+  OCTAVE_DEPRECATED (7, "use 'octave_value::non_const_unary_op' instead")
+  octave_value& do_non_const_unary_op (unary_op op)
   {
-    return do_colon_op (base, octave_value (), limit, is_for_cmd_expr);
+    return non_const_unary_op (op);
   }
 
-  friend OCTINTERP_API octave_value do_colon_op (const octave_value& base,
-                                                 const octave_value& increment,
-                                                 const octave_value& limit,
-                                                 bool is_for_cmd_expr);
+  octave_value& non_const_unary_op (unary_op op, const std::string& type,
+                                    const std::list<octave_value_list>& idx);
+
+  OCTAVE_DEPRECATED (7, "use 'octave_value::non_const_unary_op' instead")
+  octave_value& do_non_const_unary_op (unary_op op, const std::string& type,
+                                       const std::list<octave_value_list>& idx)
+  {
+    return non_const_unary_op (op, type, idx);
+  }
 
   const octave_base_value& get_rep (void) const { return *rep; }
 
@@ -1488,45 +1473,137 @@
 
 };
 
-// Publish externally used friend functions.  Which compiler requires
-// these extra declarations?
+// Non-member unary and binary operations on octave_value objects.
+
+namespace octave
+{
+  extern OCTINTERP_API octave_value
+  unary_op (octave::type_info& ti, octave_value::unary_op op,
+            const octave_value& a);
+
+  extern OCTINTERP_API octave_value
+  unary_op (octave_value::unary_op op, const octave_value& a);
+
+  extern OCTINTERP_API octave_value
+  binary_op (octave::type_info& ti, octave_value::binary_op op,
+             const octave_value& a, const octave_value& b);
+
+  extern OCTINTERP_API octave_value
+  binary_op (octave::type_info& ti, octave_value::compound_binary_op op,
+             const octave_value& a, const octave_value& b);
 
-extern OCTINTERP_API octave_value
-do_unary_op (octave::type_info& ti, octave_value::unary_op op,
-             const octave_value& a);
+  extern OCTINTERP_API octave_value
+  binary_op (octave_value::binary_op op, const octave_value& a,
+             const octave_value& b);
+
+  extern OCTINTERP_API octave_value
+  binary_op (octave_value::compound_binary_op op, const octave_value& a,
+             const octave_value& b);
 
-extern OCTINTERP_API octave_value
-do_unary_op (octave_value::unary_op op, const octave_value& a);
+  extern OCTINTERP_API octave_value
+  cat_op (octave::type_info& ti, const octave_value& a,
+          const octave_value& b, const Array<octave_idx_type>& ra_idx);
+
+  extern OCTINTERP_API octave_value
+  cat_op (const octave_value& a, const octave_value& b,
+          const Array<octave_idx_type>& ra_idx);
+
+  extern OCTINTERP_API octave_value
+  colon_op (const octave_value& base, const octave_value& increment,
+            const octave_value& limit, bool is_for_cmd_expr = false);
 
-extern OCTINTERP_API octave_value
-do_binary_op (octave::type_info& ti, octave_value::binary_op op,
-              const octave_value& a, const octave_value& b);
+  inline octave_value
+  colon_op (const octave_value& base, const octave_value& limit,
+            bool is_for_cmd_expr = false)
+  {
+    return colon_op (base, octave_value (), limit, is_for_cmd_expr);
+  }
+}
+
+OCTAVE_DEPRECATED (7, "use 'octave::unary_op' instead")
+inline octave_value
+do_unary_op (octave::type_info& ti, octave_value::unary_op op,
+             const octave_value& a)
+{
+  return octave::unary_op (ti, op, a);
+}
 
-extern OCTINTERP_API octave_value
+OCTAVE_DEPRECATED (7, "use 'octave::unary_op' instead")
+inline octave_value
+do_unary_op (octave_value::unary_op op, const octave_value& a)
+{
+  return octave::unary_op (op, a);
+
+}
+OCTAVE_DEPRECATED (7, "use 'octave::binary_op' instead")
+inline octave_value
+do_binary_op (octave::type_info& ti, octave_value::binary_op op,
+              const octave_value& a, const octave_value& b)
+{
+  return octave::binary_op (ti, op, a, b);
+}
+
+OCTAVE_DEPRECATED (7, "use 'octave::binary_op' instead")
+inline octave_value
 do_binary_op (octave::type_info& ti, octave_value::compound_binary_op op,
-              const octave_value& a, const octave_value& b);
+              const octave_value& a, const octave_value& b)
+{
+  return octave::binary_op (ti, op, a, b);
+}
 
-extern OCTINTERP_API octave_value
+OCTAVE_DEPRECATED (7, "use 'octave::binary_op' instead")
+inline octave_value
 do_binary_op (octave_value::binary_op op, const octave_value& a,
-              const octave_value& b);
+              const octave_value& b)
+{
+  return octave::binary_op (op, a, b);
+}
 
-extern OCTINTERP_API octave_value
+OCTAVE_DEPRECATED (7, "use 'octave::binary_op' instead")
+inline octave_value
 do_binary_op (octave_value::compound_binary_op op, const octave_value& a,
-              const octave_value& b);
+              const octave_value& b)
+{
+  return octave::binary_op (op, a, b);
+}
 
-extern OCTINTERP_API octave_value
+OCTAVE_DEPRECATED (7, "use 'octave::cat_op' instead")
+inline octave_value
 do_cat_op (octave::type_info& ti, const octave_value& a,
-           const octave_value& b, const Array<octave_idx_type>& ra_idx);
+           const octave_value& b, const Array<octave_idx_type>& ra_idx)
+{
+  return octave::cat_op (ti, a, b, ra_idx);
+}
 
-extern OCTINTERP_API octave_value
+OCTAVE_DEPRECATED (7, "use 'octave::cat_op' instead")
+inline octave_value
 do_cat_op (const octave_value& a, const octave_value& b,
-           const Array<octave_idx_type>& ra_idx);
+           const Array<octave_idx_type>& ra_idx)
+{
+  return octave::cat_op (a, b, ra_idx);
+}
 
-#define OV_UNOP_FN(name)                        \
-  inline octave_value                           \
-  name (const octave_value& a)                  \
-  {                                             \
-    return do_unary_op (octave_value::name, a); \
+OCTAVE_DEPRECATED (7, "use 'octave::colon_op' instead")
+inline octave_value
+do_colon_op (const octave_value& base, const octave_value& increment,
+             const octave_value& limit, bool is_for_cmd_expr = false)
+{
+  return octave::colon_op (base, increment, limit, is_for_cmd_expr);
+}
+
+OCTAVE_DEPRECATED (7, "use 'octave::colon_op' instead")
+inline octave_value
+do_colon_op (const octave_value& base, const octave_value& limit,
+             bool is_for_cmd_expr = false)
+{
+  return octave::colon_op (base, limit, is_for_cmd_expr);
+}
+
+#define OV_UNOP_FN(name)                                \
+  inline octave_value                                   \
+  name (const octave_value& a)                          \
+  {                                                     \
+    return octave::unary_op (octave_value::name, a);    \
   }
 
 #define OV_UNOP_OP(name, op)                    \
@@ -1552,11 +1629,11 @@
 //   incr
 //   decr
 
-#define OV_BINOP_FN(name)                               \
-  inline octave_value                                   \
-  name (const octave_value& a1, const octave_value& a2) \
-  {                                                     \
-    return do_binary_op (octave_value::name, a1, a2);   \
+#define OV_BINOP_FN(name)                                       \
+  inline octave_value                                           \
+  name (const octave_value& a1, const octave_value& a2)         \
+  {                                                             \
+    return octave::binary_op (octave_value::name, a1, a2);      \
   }
 
 #define OV_BINOP_OP(name, op)                                   \
@@ -1594,11 +1671,11 @@
 
 OV_BINOP_FN (op_struct_ref)
 
-#define OV_COMP_BINOP_FN(name)                          \
-  inline octave_value                                   \
-  name (const octave_value& a1, const octave_value& a2) \
-  {                                                     \
-    return do_binary_op (octave_value::name, a1, a2);   \
+#define OV_COMP_BINOP_FN(name)                                  \
+  inline octave_value                                           \
+  name (const octave_value& a1, const octave_value& a2)         \
+  {                                                             \
+    return octave::binary_op (octave_value::name, a1, a2);      \
   }
 
 OV_COMP_BINOP_FN (op_trans_mul)
--- a/libinterp/parse-tree/oct-lvalue.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/parse-tree/oct-lvalue.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -94,10 +94,10 @@
     return retval;
   }
 
-  void octave_lvalue::do_unary_op (octave_value::unary_op op)
+  void octave_lvalue::unary_op (octave_value::unary_op op)
   {
     if (! is_black_hole ())
-      m_frame->do_non_const_unary_op (op, m_sym, m_type, m_idx);
+      m_frame->non_const_unary_op (op, m_sym, m_type, m_idx);
   }
 
   octave_value octave_lvalue::value (void) const
--- a/libinterp/parse-tree/oct-lvalue.h	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/parse-tree/oct-lvalue.h	Thu Jul 30 16:16:04 2020 -0400
@@ -80,7 +80,13 @@
 
     bool index_is_colon (void) const;
 
-    void do_unary_op (octave_value::unary_op op);
+    void unary_op (octave_value::unary_op op);
+
+    OCTAVE_DEPRECATED (7, "use 'octave_lvalue::unary_op' instead")
+    void do_unary_op (octave_value::unary_op op)
+    {
+      return unary_op (op);
+    }
 
     octave_value value (void) const;
 
--- a/libinterp/parse-tree/pt-binop.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/parse-tree/pt-binop.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -137,7 +137,7 @@
 
                 type_info& ti = interp.get_type_info ();
 
-                val = ::do_binary_op (ti, m_etype, a, b);
+                val = binary_op (ti, m_etype, a, b);
               }
           }
       }
--- a/libinterp/parse-tree/pt-cbinop.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/parse-tree/pt-cbinop.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -54,7 +54,7 @@
 
                 type_info& ti = interp.get_type_info ();
 
-                val = ::do_binary_op (ti, m_etype, a, b);
+                val = binary_op (ti, m_etype, a, b);
               }
           }
       }
--- a/libinterp/parse-tree/pt-colon.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/parse-tree/pt-colon.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -73,6 +73,6 @@
         ov_limit = m_limit->evaluate (tw);
       }
 
-    return do_colon_op (ov_base, ov_increment, ov_limit, is_for_cmd_expr ());
+    return colon_op (ov_base, ov_increment, ov_limit, is_for_cmd_expr ());
   }
 }
--- a/libinterp/parse-tree/pt-eval.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/parse-tree/pt-eval.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -2606,9 +2606,9 @@
                 if (m_echo_state)
                   m_echo_file_pos = line;
 
-                // do_index_op expects one-based indices.
+                // index_op expects one-based indices.
                 idx(iidx) = i;
-                octave_value val = arg.do_index_op (idx);
+                octave_value val = arg.index_op (idx);
 
                 ult.assign (octave_value::op_asn_eq, val);
 
--- a/libinterp/parse-tree/pt-tm-const.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/parse-tree/pt-tm-const.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -461,7 +461,7 @@
     // full.  This is done since it means that there is no recopying of
     // data, as would happen if we used a single resize.  It should be
     // noted that resize operation is also significantly slower than the
-    // do_cat_op function, so it makes sense to have an empty matrix and
+    // cat_op function, so it makes sense to have an empty matrix and
     // copy all data.
     //
     // We might also start with a empty octave_value using
@@ -532,7 +532,7 @@
             if (elt.isempty ())
               continue;
 
-            ctmp = do_cat_op (ti, ctmp, elt, ra_idx);
+            ctmp = cat_op (ti, ctmp, elt, ra_idx);
 
             ra_idx (1) += elt.columns ();
           }
--- a/libinterp/parse-tree/pt-unop.cc	Thu Jul 30 16:15:03 2020 -0400
+++ b/libinterp/parse-tree/pt-unop.cc	Thu Jul 30 16:16:04 2020 -0400
@@ -71,7 +71,7 @@
             profiler::enter<tree_prefix_expression>
               block (tw.get_profiler (), *this);
 
-            op_ref.do_unary_op (m_etype);
+            op_ref.unary_op (m_etype);
 
             val = op_ref.value ();
           }
@@ -87,14 +87,14 @@
                 // Attempt to do the operation in-place if it is unshared
                 // (a temporary expression).
                 if (op_val.get_count () == 1)
-                  val = op_val.do_non_const_unary_op (m_etype);
+                  val = op_val.non_const_unary_op (m_etype);
                 else
                   {
                     interpreter& interp = tw.get_interpreter ();
 
                     type_info& ti = interp.get_type_info ();
 
-                    val = ::do_unary_op (ti, m_etype, op_val);
+                    val = unary_op (ti, m_etype, op_val);
                   }
               }
           }
@@ -134,7 +134,7 @@
             profiler::enter<tree_postfix_expression>
               block (tw.get_profiler (), *this);
 
-            ref.do_unary_op (m_etype);
+            ref.unary_op (m_etype);
           }
         else
           {
@@ -149,7 +149,7 @@
 
                 type_info& ti = interp.get_type_info ();
 
-                val = ::do_unary_op (ti, m_etype, op_val);
+                val = unary_op (ti, m_etype, op_val);
               }
           }
       }