changeset 21647:66cae7a6dc47

eliminate some macros for operator definitions * ops.h (CAST_UNOP_ARG, CAST_BINOP_ARGS, CAST_CONV_ARG, ASSIGNOPDECL, NULLASSIGNOPDECL, ASSIGNANYOPDECL, DEFASSIGNOP, DEFASSIGNOP_FN, UNOPDECL, BINOPDECL, CATOPDECL): Delete macros. * make_int.cc, ov-bool-mat.cc, ov-bool-sparse.cc, ov-bool.cc, ov-complex.cc, ov-cx-diag.cc, ov-cx-mat.cc, ov-flt-cx-diag.cc, ov-flt-re-diag.cc, ov-lazy-idx.cc, ov-null-mat.cc, ov-perm.cc, ov-range.cc, ov-re-diag.cc, ov-re-mat.cc, ov-scalar.cc, ov-str-mat.cc, op-b-b.cc, op-b-bm.cc, op-b-sbm.cc, op-bm-bm.cc, op-bm-sbm.cc, op-cdm-cdm.cc, op-cell.cc, op-chm.cc, op-cm-cm.cc, op-cm-cs.cc, op-cm-m.cc, op-cm-s.cc, op-cm-scm.cc, op-cm-sm.cc, op-cs-cm.cc, op-cs-cs.cc, op-cs-m.cc, op-cs-s.cc, op-cs-scm.cc, op-cs-sm.cc, op-dm-dm.cc, op-dm-scm.cc, op-dm-sm.cc, op-dm-template.cc, op-dms-template.cc, op-fcdm-fcdm.cc, op-fcm-fcm.cc, op-fcm-fcs.cc, op-fcm-fm.cc, op-fcm-fs.cc, op-fcn.cc, op-fcs-fcm.cc, op-fcs-fcs.cc, op-fcs-fm.cc, op-fcs-fs.cc, op-fdm-fdm.cc, op-fm-fcm.cc, op-fm-fcs.cc, op-fm-fm.cc, op-fm-fs.cc, op-fs-fcm.cc, op-fs-fcs.cc, op-fs-fm.cc, op-fs-fs.cc, op-int-conv.cc, op-int.h, op-m-cm.cc, op-m-cs.cc, op-m-m.cc, op-m-s.cc, op-m-scm.cc, op-m-sm.cc, op-pm-pm.cc, op-pm-scm.cc, op-pm-sm.cc, op-pm-template.cc, op-range.cc, op-s-cm.cc, op-s-cs.cc, op-s-m.cc, op-s-s.cc, op-s-scm.cc, op-s-sm.cc, op-sbm-b.cc, op-sbm-bm.cc, op-sbm-sbm.cc, op-scm-cm.cc, op-scm-cs.cc, op-scm-m.cc, op-scm-s.cc, op-scm-scm.cc, op-scm-sm.cc, op-sm-cm.cc, op-sm-cs.cc, op-sm-m.cc, op-sm-s.cc, op-sm-scm.cc, op-sm-sm.cc, op-str-m.cc, op-str-s.cc, op-str-str.cc, op-struct.cc, ops.h: Expand eliminated macros in place.
author John W. Eaton <jwe@octave.org>
date Wed, 27 Apr 2016 16:13:40 -0400
parents 3cddf1e65ccf
children 1eabc3e24a53
files examples/code/make_int.cc libinterp/octave-value/ov-bool-mat.cc libinterp/octave-value/ov-bool-sparse.cc libinterp/octave-value/ov-bool.cc libinterp/octave-value/ov-complex.cc libinterp/octave-value/ov-cx-diag.cc libinterp/octave-value/ov-cx-mat.cc libinterp/octave-value/ov-flt-cx-diag.cc libinterp/octave-value/ov-flt-re-diag.cc libinterp/octave-value/ov-lazy-idx.cc libinterp/octave-value/ov-null-mat.cc libinterp/octave-value/ov-perm.cc libinterp/octave-value/ov-range.cc libinterp/octave-value/ov-re-diag.cc libinterp/octave-value/ov-re-mat.cc libinterp/octave-value/ov-scalar.cc libinterp/octave-value/ov-str-mat.cc libinterp/operators/op-b-b.cc libinterp/operators/op-b-bm.cc libinterp/operators/op-b-sbm.cc libinterp/operators/op-bm-bm.cc libinterp/operators/op-bm-sbm.cc libinterp/operators/op-cdm-cdm.cc libinterp/operators/op-cell.cc libinterp/operators/op-chm.cc libinterp/operators/op-cm-cm.cc libinterp/operators/op-cm-cs.cc libinterp/operators/op-cm-m.cc libinterp/operators/op-cm-s.cc libinterp/operators/op-cm-scm.cc libinterp/operators/op-cm-sm.cc libinterp/operators/op-cs-cm.cc libinterp/operators/op-cs-cs.cc libinterp/operators/op-cs-m.cc libinterp/operators/op-cs-s.cc libinterp/operators/op-cs-scm.cc libinterp/operators/op-cs-sm.cc libinterp/operators/op-dm-dm.cc libinterp/operators/op-dm-scm.cc libinterp/operators/op-dm-sm.cc libinterp/operators/op-dm-template.cc libinterp/operators/op-dms-template.cc libinterp/operators/op-fcdm-fcdm.cc libinterp/operators/op-fcm-fcm.cc libinterp/operators/op-fcm-fcs.cc libinterp/operators/op-fcm-fm.cc libinterp/operators/op-fcm-fs.cc libinterp/operators/op-fcn.cc libinterp/operators/op-fcs-fcm.cc libinterp/operators/op-fcs-fcs.cc libinterp/operators/op-fcs-fm.cc libinterp/operators/op-fcs-fs.cc libinterp/operators/op-fdm-fdm.cc libinterp/operators/op-fm-fcm.cc libinterp/operators/op-fm-fcs.cc libinterp/operators/op-fm-fm.cc libinterp/operators/op-fm-fs.cc libinterp/operators/op-fs-fcm.cc libinterp/operators/op-fs-fcs.cc libinterp/operators/op-fs-fm.cc libinterp/operators/op-fs-fs.cc libinterp/operators/op-int-conv.cc libinterp/operators/op-int.h libinterp/operators/op-m-cm.cc libinterp/operators/op-m-cs.cc libinterp/operators/op-m-m.cc libinterp/operators/op-m-s.cc libinterp/operators/op-m-scm.cc libinterp/operators/op-m-sm.cc libinterp/operators/op-pm-pm.cc libinterp/operators/op-pm-scm.cc libinterp/operators/op-pm-sm.cc libinterp/operators/op-pm-template.cc libinterp/operators/op-range.cc libinterp/operators/op-s-cm.cc libinterp/operators/op-s-cs.cc libinterp/operators/op-s-m.cc libinterp/operators/op-s-s.cc libinterp/operators/op-s-scm.cc libinterp/operators/op-s-sm.cc libinterp/operators/op-sbm-b.cc libinterp/operators/op-sbm-bm.cc libinterp/operators/op-sbm-sbm.cc libinterp/operators/op-scm-cm.cc libinterp/operators/op-scm-cs.cc libinterp/operators/op-scm-m.cc libinterp/operators/op-scm-s.cc libinterp/operators/op-scm-scm.cc libinterp/operators/op-scm-sm.cc libinterp/operators/op-sm-cm.cc libinterp/operators/op-sm-cs.cc libinterp/operators/op-sm-m.cc libinterp/operators/op-sm-s.cc libinterp/operators/op-sm-scm.cc libinterp/operators/op-sm-sm.cc libinterp/operators/op-str-m.cc libinterp/operators/op-str-s.cc libinterp/operators/op-str-str.cc libinterp/operators/op-struct.cc libinterp/operators/ops.h
diffstat 100 files changed, 957 insertions(+), 675 deletions(-) [+]
line wrap: on
line diff
--- a/examples/code/make_int.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/examples/code/make_int.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -124,9 +124,10 @@
 #endif
 
 #define DEFUNOP_OP(name, t, op) \
-  UNOPDECL (name, a) \
+  static octave_value \
+  CONCAT2(oct_unop_, name) (const octave_base_value& a) \
   { \
-    CAST_UNOP_ARG (const octave_ ## t&); \
+    const octave_ ## t& v = dynamic_cast<const octave_ ## t&> (a); \
     return octave_value (new octave_integer (op v.t ## _value ())); \
   }
 
@@ -143,9 +144,11 @@
 #endif
 
 #define DEFBINOP_OP(name, t1, t2, op) \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    const octave_ ## t1& v1 = dynamic_cast<const octave_ ## t1&> (a1); \
+    const octave_ ## t2& v2 = dynamic_cast<const octave_ ## t2&> (a2); \
     return octave_value \
       (new octave_integer (v1.t1 ## _value () op v2.t2 ## _value ())); \
   }
@@ -158,7 +161,8 @@
 
 DEFBINOP (div, integer, integer)
 {
-  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
+  const octave_integer& v1 = dynamic_cast<const octave_integer&> (a1);
+  const octave_integer& v2 = dynamic_cast<const octave_integer&> (a2);
 
   int d = v2.integer_value ();
 
@@ -171,7 +175,8 @@
 
 DEFBINOP (i_s_div, integer, scalar)
 {
-  CAST_BINOP_ARGS (const octave_integer&, const octave_scalar&);
+  const octave_integer& v1 = dynamic_cast<const octave_integer&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
 
@@ -183,7 +188,8 @@
 
 DEFBINOP (ldiv, integer, integer)
 {
-  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
+  const octave_integer& v1 = dynamic_cast<const octave_integer&> (a1);
+  const octave_integer& v2 = dynamic_cast<const octave_integer&> (a2);
 
   int d = v1.integer_value ();
 
@@ -204,7 +210,8 @@
 
 DEFBINOP (el_div, integer, integer)
 {
-  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
+  const octave_integer& v1 = dynamic_cast<const octave_integer&> (a1);
+  const octave_integer& v2 = dynamic_cast<const octave_integer&> (a2);
 
   int d = v2.integer_value ();
 
@@ -216,7 +223,8 @@
 
 DEFBINOP (el_ldiv, integer, integer)
 {
-  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
+  const octave_integer& v1 = dynamic_cast<const octave_integer&> (a1);
+  const octave_integer& v2 = dynamic_cast<const octave_integer&> (a2);
 
   int d = v1.integer_value ();
 
--- a/libinterp/octave-value/ov-bool-mat.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-bool-mat.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -60,7 +60,7 @@
 static octave_base_value *
 default_numeric_conversion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_bool_matrix&);
+  const octave_bool_matrix& v = dynamic_cast<const octave_bool_matrix&> (a);
 
   return new octave_matrix (NDArray (v.bool_array_value ()));
 }
--- a/libinterp/octave-value/ov-bool-sparse.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-bool-sparse.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -58,7 +58,7 @@
 static octave_base_value *
 default_numeric_conversion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_sparse_bool_matrix&);
+  const octave_sparse_bool_matrix& v = dynamic_cast<const octave_sparse_bool_matrix&> (a);
 
   return
     new octave_sparse_matrix (SparseMatrix (v.sparse_bool_matrix_value ()));
--- a/libinterp/octave-value/ov-bool.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-bool.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -59,7 +59,7 @@
 static octave_base_value *
 default_numeric_conversion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_bool&);
+  const octave_bool& v = dynamic_cast<const octave_bool&> (a);
 
   return new octave_scalar (v.bool_value ());
 }
--- a/libinterp/octave-value/ov-complex.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-complex.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -89,7 +89,7 @@
 static octave_base_value *
 default_numeric_demotion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_complex&);
+  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
 
   return new octave_float_complex (v.float_complex_value ());
 }
--- a/libinterp/octave-value/ov-cx-diag.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-cx-diag.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -43,7 +43,7 @@
 static octave_base_value *
 default_numeric_conversion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_complex_diag_matrix&);
+  const octave_complex_diag_matrix& v = dynamic_cast<const octave_complex_diag_matrix&> (a);
 
   return new octave_complex_matrix (v.complex_matrix_value ());
 }
@@ -59,7 +59,7 @@
 static octave_base_value *
 default_numeric_demotion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_complex_diag_matrix&);
+  const octave_complex_diag_matrix& v = dynamic_cast<const octave_complex_diag_matrix&> (a);
 
   return new octave_float_complex_diag_matrix
                (v.float_complex_diag_matrix_value ());
--- a/libinterp/octave-value/ov-cx-mat.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-cx-mat.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -66,7 +66,7 @@
 static octave_base_value *
 default_numeric_demotion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_complex_matrix&);
+  const octave_complex_matrix& v = dynamic_cast<const octave_complex_matrix&> (a);
 
   return new octave_float_complex_matrix (v.float_complex_array_value ());
 }
--- a/libinterp/octave-value/ov-flt-cx-diag.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-flt-cx-diag.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -42,7 +42,7 @@
 static octave_base_value *
 default_numeric_conversion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_float_complex_diag_matrix&);
+  const octave_float_complex_diag_matrix& v = dynamic_cast<const octave_float_complex_diag_matrix&> (a);
 
   return new octave_float_complex_matrix (v.float_complex_matrix_value ());
 }
--- a/libinterp/octave-value/ov-flt-re-diag.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-flt-re-diag.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -41,7 +41,7 @@
 static octave_base_value *
 default_numeric_conversion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_float_diag_matrix&);
+  const octave_float_diag_matrix& v = dynamic_cast<const octave_float_diag_matrix&> (a);
 
   return new octave_float_matrix (v.float_matrix_value ());
 }
--- a/libinterp/octave-value/ov-lazy-idx.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-lazy-idx.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -35,7 +35,7 @@
 static octave_base_value *
 default_numeric_conversion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_lazy_index&);
+  const octave_lazy_index& v = dynamic_cast<const octave_lazy_index&> (a);
 
   return v.full_value ().clone ();
 }
--- a/libinterp/octave-value/ov-null-mat.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-null-mat.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -37,7 +37,7 @@
 default_null_matrix_numeric_conversion_function (const octave_base_value& a)
 {
   // The cast is not necessary?
-  // CAST_CONV_ARG (const octave_null_matrix&);
+  // const octave_null_matrix& v = dynamic_cast<const octave_null_matrix&> (a);
 
   return a.empty_clone ();
 }
@@ -58,7 +58,7 @@
 default_null_str_numeric_conversion_function (const octave_base_value& a)
 {
   // The cast is not necessary?
-  // CAST_CONV_ARG (const octave_null_str&);
+  // const octave_null_str& v = dynamic_cast<const octave_null_str&> (a);
 
   return a.empty_clone ();
 }
@@ -80,7 +80,7 @@
 default_null_sq_str_numeric_conversion_function (const octave_base_value& a)
 {
   // The cast is not necessary?
-  // CAST_CONV_ARG (const octave_null_sq_str&);
+  // const octave_null_sq_str& v = dynamic_cast<const octave_null_sq_str&> (a);
 
   return a.empty_clone ();
 }
--- a/libinterp/octave-value/ov-perm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-perm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -413,7 +413,7 @@
 static octave_base_value *
 default_numeric_conversion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_perm_matrix&);
+  const octave_perm_matrix& v = dynamic_cast<const octave_perm_matrix&> (a);
 
   return new octave_matrix (v.matrix_value ());
 }
--- a/libinterp/octave-value/ov-range.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-range.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -55,7 +55,7 @@
 static octave_base_value *
 default_numeric_conversion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_range&);
+  const octave_range& v = dynamic_cast<const octave_range&> (a);
 
   return new octave_matrix (v.matrix_value ());
 }
--- a/libinterp/octave-value/ov-re-diag.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-re-diag.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -42,7 +42,7 @@
 static octave_base_value *
 default_numeric_conversion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_diag_matrix&);
+  const octave_diag_matrix& v = dynamic_cast<const octave_diag_matrix&> (a);
 
   return new octave_matrix (v.matrix_value ());
 }
@@ -57,7 +57,7 @@
 static octave_base_value *
 default_numeric_demotion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_diag_matrix&);
+  const octave_diag_matrix& v = dynamic_cast<const octave_diag_matrix&> (a);
 
   return new octave_float_diag_matrix (v.float_diag_matrix_value ());
 }
--- a/libinterp/octave-value/ov-re-mat.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-re-mat.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -77,7 +77,7 @@
 static octave_base_value *
 default_numeric_demotion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_matrix&);
+  const octave_matrix& v = dynamic_cast<const octave_matrix&> (a);
 
   return new octave_float_matrix (v.float_array_value ());
 }
--- a/libinterp/octave-value/ov-scalar.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-scalar.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -66,7 +66,7 @@
 static octave_base_value *
 default_numeric_demotion_function (const octave_base_value& a)
 {
-  CAST_CONV_ARG (const octave_scalar&);
+  const octave_scalar& v = dynamic_cast<const octave_scalar&> (a);
 
   return new octave_float_scalar (v.float_value ());
 }
--- a/libinterp/octave-value/ov-str-mat.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/octave-value/ov-str-mat.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -64,7 +64,7 @@
 {
   octave_base_value *retval = 0;
 
-  CAST_CONV_ARG (const octave_char_matrix_str&);
+  const octave_char_matrix_str& v = dynamic_cast<const octave_char_matrix_str&> (a);
 
   NDArray nda = v.array_value (true);
 
--- a/libinterp/operators/op-b-b.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-b-b.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -44,15 +44,17 @@
 
 DEFUNOP_OP (not, bool, !)
 
-UNOPDECL (uplus, a)
+static octave_value
+oct_unop_uplus (const octave_base_value& a)
 {
-  CAST_UNOP_ARG (const octave_bool&);
+  const octave_bool& v = dynamic_cast<const octave_bool&> (a);
   return octave_value (v.double_value ());
 }
 
-UNOPDECL (uminus, a)
+static octave_value
+oct_unop_uminus (const octave_base_value& a)
 {
-  CAST_UNOP_ARG (const octave_bool&);
+  const octave_bool& v = dynamic_cast<const octave_bool&> (a);
   return octave_value (- v.double_value ());
 }
 
--- a/libinterp/operators/op-b-bm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-b-bm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -56,7 +56,7 @@
 
 DEFCONV (bool_matrix_conv, bool, bool_matrix)
 {
-  CAST_CONV_ARG (const octave_bool&);
+  const octave_bool& v = dynamic_cast<const octave_bool&> (a);
 
   return new octave_bool_matrix (v.bool_matrix_value ());
 }
--- a/libinterp/operators/op-b-sbm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-b-sbm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -47,7 +47,8 @@
 
 DEFCATOP (b_sbm, bool, sparse_bool_matrix)
 {
-  CAST_BINOP_ARGS (octave_bool&, const octave_sparse_bool_matrix&);
+  octave_bool& v1 = dynamic_cast<octave_bool&> (a1);
+  const octave_sparse_bool_matrix& v2 = dynamic_cast<const octave_sparse_bool_matrix&> (a2);
   SparseBoolMatrix tmp (1, 1, v1.bool_value ());
   return octave_value (tmp. concat (v2.sparse_bool_matrix_value (),
                                     ra_idx));
@@ -55,21 +56,23 @@
 
 DEFCATOP (b_sm, bool, sparse_matrix)
 {
-  CAST_BINOP_ARGS (octave_bool&, const octave_sparse_matrix&);
+  octave_bool& v1 = dynamic_cast<octave_bool&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
   SparseMatrix tmp (1, 1, v1.scalar_value ());
   return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
 }
 
 DEFCATOP (s_sbm, scalar, sparse_bool_matrix)
 {
-  CAST_BINOP_ARGS (octave_scalar&, const octave_sparse_bool_matrix&);
+  octave_scalar& v1 = dynamic_cast<octave_scalar&> (a1);
+  const octave_sparse_bool_matrix& v2 = dynamic_cast<const octave_sparse_bool_matrix&> (a2);
   SparseMatrix tmp (1, 1, v1.scalar_value ());
   return octave_value(tmp. concat (v2.sparse_matrix_value (), ra_idx));
 }
 
 DEFCONV (sparse_bool_matrix_conv, bool, sparse_bool_matrix)
 {
-  CAST_CONV_ARG (const octave_bool&);
+  const octave_bool& v = dynamic_cast<const octave_bool&> (a);
 
   return new octave_sparse_bool_matrix
     (SparseBoolMatrix (1, 1, v.bool_value ()));
--- a/libinterp/operators/op-bm-bm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-bm-bm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -58,7 +58,7 @@
 
 DEFUNOP (transpose, bool_matrix)
 {
-  CAST_UNOP_ARG (const octave_bool_matrix&);
+  const octave_bool_matrix& v = dynamic_cast<const octave_bool_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
--- a/libinterp/operators/op-bm-sbm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-bm-sbm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -49,7 +49,8 @@
 
 DEFCATOP (bm_sbm, bool_matrix, sparse_bool_matrix)
 {
-  CAST_BINOP_ARGS (octave_bool_matrix&, const octave_sparse_bool_matrix&);
+  octave_bool_matrix& v1 = dynamic_cast<octave_bool_matrix&> (a1);
+  const octave_sparse_bool_matrix& v2 = dynamic_cast<const octave_sparse_bool_matrix&> (a2);
   SparseBoolMatrix tmp (v1.bool_matrix_value ());
   return octave_value (tmp. concat (v2.sparse_bool_matrix_value (),
                                     ra_idx));
@@ -57,21 +58,23 @@
 
 DEFCATOP (m_sbm, matrix, sparse_bool_matrix)
 {
-  CAST_BINOP_ARGS (octave_matrix&, const octave_sparse_bool_matrix&);
+  octave_matrix& v1 = dynamic_cast<octave_matrix&> (a1);
+  const octave_sparse_bool_matrix& v2 = dynamic_cast<const octave_sparse_bool_matrix&> (a2);
   SparseMatrix tmp (v1.matrix_value ());
   return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
 }
 
 DEFCATOP (bm_sm, bool_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (octave_bool_matrix&, const octave_sparse_matrix&);
+  octave_bool_matrix& v1 = dynamic_cast<octave_bool_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
   SparseMatrix tmp (v1.matrix_value ());
   return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
 }
 
 DEFCONV (sparse_bool_matrix_conv, bool_matrix, sparse_bool_matrix)
 {
-  CAST_CONV_ARG (const octave_bool_matrix&);
+  const octave_bool_matrix& v = dynamic_cast<const octave_bool_matrix&> (a);
   return new octave_sparse_bool_matrix
     (SparseBoolMatrix (v.bool_matrix_value ()));
 }
--- a/libinterp/operators/op-cdm-cdm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cdm-cdm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -42,13 +42,13 @@
 
 DEFUNOP (transpose, complex_diag_matrix)
 {
-  CAST_UNOP_ARG (const octave_complex_diag_matrix&);
+  const octave_complex_diag_matrix& v = dynamic_cast<const octave_complex_diag_matrix&> (a);
   return octave_value (v.complex_diag_matrix_value ().transpose ());
 }
 
 DEFUNOP (hermitian, complex_diag_matrix)
 {
-  CAST_UNOP_ARG (const octave_complex_diag_matrix&);
+  const octave_complex_diag_matrix& v = dynamic_cast<const octave_complex_diag_matrix&> (a);
   return octave_value (v.complex_diag_matrix_value ().hermitian ());
 }
 
@@ -60,8 +60,8 @@
 
 DEFBINOP (div, complex_diag_matrix, complex_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
-                   const octave_complex_diag_matrix&);
+  const octave_complex_diag_matrix& v1 = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+  const octave_complex_diag_matrix& v2 = dynamic_cast<const octave_complex_diag_matrix&> (a2);
 
   return xdiv (v1.complex_diag_matrix_value (),
                v2.complex_diag_matrix_value ());
@@ -69,8 +69,8 @@
 
 DEFBINOP (ldiv, complex_diag_matrix, complex_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
-                   const octave_complex_diag_matrix&);
+  const octave_complex_diag_matrix& v1 = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+  const octave_complex_diag_matrix& v2 = dynamic_cast<const octave_complex_diag_matrix&> (a2);
 
   return xleftdiv (v1.complex_diag_matrix_value (),
                    v2.complex_diag_matrix_value ());
@@ -78,14 +78,14 @@
 
 CONVDECL (complex_diag_matrix_to_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_complex_diag_matrix&);
+  const octave_complex_diag_matrix& v = dynamic_cast<const octave_complex_diag_matrix&> (a);
 
   return new octave_complex_matrix (v.complex_matrix_value ());
 }
 
 CONVDECL (complex_diag_matrix_to_float_complex_diag_matrix)
 {
-  CAST_CONV_ARG (const octave_complex_diag_matrix&);
+  const octave_complex_diag_matrix& v = dynamic_cast<const octave_complex_diag_matrix&> (a);
 
   return
     new octave_float_complex_diag_matrix (v.float_complex_diag_matrix_value ());
--- a/libinterp/operators/op-cell.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cell.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -38,7 +38,7 @@
 
 DEFUNOP (transpose, cell)
 {
-  CAST_UNOP_ARG (const octave_cell&);
+  const octave_cell& v = dynamic_cast<const octave_cell&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
--- a/libinterp/operators/op-chm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-chm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -39,7 +39,7 @@
 
 DEFUNOP (transpose, char_matrix)
 {
-  CAST_UNOP_ARG (const octave_char_matrix&);
+  const octave_char_matrix& v = dynamic_cast<const octave_char_matrix&> (a);
 
   return octave_value (v.matrix_value ().transpose ());
 }
@@ -49,7 +49,8 @@
 
 DEFCATOP (chm_s, char_matrix, scalar)
 {
-  CAST_BINOP_ARGS (octave_char_matrix&, const octave_scalar&);
+  octave_char_matrix& v1 = dynamic_cast<octave_char_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   warn_implicit_conversion ("Octave:num-to-str",
                             v2.type_name (), v1.type_name ());
@@ -60,7 +61,8 @@
 
 DEFCATOP (chm_m, char_matrix, matrix)
 {
-  CAST_BINOP_ARGS (octave_char_matrix&, const octave_matrix&);
+  octave_char_matrix& v1 = dynamic_cast<octave_char_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   warn_implicit_conversion ("Octave:num-to-str",
                             v2.type_name (), v1.type_name ());
@@ -71,7 +73,8 @@
 
 DEFCATOP (s_chm, scalar, char_matrix)
 {
-  CAST_BINOP_ARGS (octave_scalar&, const octave_char_matrix&);
+  octave_scalar& v1 = dynamic_cast<octave_scalar&> (a1);
+  const octave_char_matrix& v2 = dynamic_cast<const octave_char_matrix&> (a2);
 
   warn_implicit_conversion ("Octave:num-to-str",
                             v1.type_name (), v2.type_name ());
@@ -82,7 +85,8 @@
 
 DEFCATOP (m_chm, matrix, char_matrix)
 {
-  CAST_BINOP_ARGS (octave_matrix&, const octave_char_matrix&);
+  octave_matrix& v1 = dynamic_cast<octave_matrix&> (a1);
+  const octave_char_matrix& v2 = dynamic_cast<const octave_char_matrix&> (a2);
 
   warn_implicit_conversion ("Octave:num-to-str",
                             v1.type_name (), v2.type_name ());
--- a/libinterp/operators/op-cm-cm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cm-cm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -43,7 +43,7 @@
 
 DEFUNOP (transpose, complex_matrix)
 {
-  CAST_UNOP_ARG (const octave_complex_matrix&);
+  const octave_complex_matrix& v = dynamic_cast<const octave_complex_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -53,7 +53,7 @@
 
 DEFUNOP (hermitian, complex_matrix)
 {
-  CAST_UNOP_ARG (const octave_complex_matrix&);
+  const octave_complex_matrix& v = dynamic_cast<const octave_complex_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("complex-conjugate transpose not defined for N-D objects");
@@ -76,7 +76,8 @@
 
 DEFBINOP (div, complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   ComplexMatrix ret = xdiv (v1.complex_matrix_value (),
@@ -93,7 +94,8 @@
 
 DEFBINOP (ldiv, complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (),
@@ -105,7 +107,8 @@
 
 DEFBINOP (trans_mul, complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   return octave_value(xgemm (v1.complex_matrix_value (),
                              v2.complex_matrix_value (),
                              blas_trans, blas_no_trans));
@@ -113,7 +116,8 @@
 
 DEFBINOP (mul_trans, complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   return octave_value(xgemm (v1.complex_matrix_value (),
                              v2.complex_matrix_value (),
                              blas_no_trans, blas_trans));
@@ -121,7 +125,8 @@
 
 DEFBINOP (herm_mul, complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   return octave_value(xgemm (v1.complex_matrix_value (),
                              v2.complex_matrix_value (),
                              blas_conj_trans, blas_no_trans));
@@ -129,7 +134,8 @@
 
 DEFBINOP (mul_herm, complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   return octave_value(xgemm (v1.complex_matrix_value (),
                              v2.complex_matrix_value (),
                              blas_no_trans, blas_conj_trans));
@@ -137,7 +143,8 @@
 
 DEFBINOP (trans_ldiv, complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (),
@@ -149,7 +156,8 @@
 
 DEFBINOP (herm_ldiv, complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (),
@@ -182,7 +190,8 @@
 
 DEFBINOP (el_ldiv, complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   return octave_value (quotient (v2.complex_array_value (),
                                  v1.complex_array_value ()));
@@ -209,7 +218,7 @@
 
 CONVDECL (complex_matrix_to_float_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_complex_matrix&);
+  const octave_complex_matrix& v = dynamic_cast<const octave_complex_matrix&> (a);
 
   return
     new octave_float_complex_matrix
--- a/libinterp/operators/op-cm-cs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cm-cs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -43,7 +43,8 @@
 
 DEFBINOP (div, complex_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v2.complex_value ();
 
@@ -57,7 +58,8 @@
 
 DEFBINOP (ldiv, complex_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   ComplexMatrix m1 = v1.complex_matrix_value ();
   ComplexMatrix m2 = v2.complex_matrix_value ();
@@ -85,7 +87,8 @@
 
 DEFBINOP (el_div, complex_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v2.complex_value ();
 
@@ -100,7 +103,8 @@
 
 DEFBINOP (el_ldiv, complex_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_complex&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   return x_el_div (v2.complex_value (), v1.complex_array_value ());
 }
--- a/libinterp/operators/op-cm-m.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cm-m.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -48,7 +48,8 @@
 
 DEFBINOP (mul_trans, complex_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   ComplexMatrix m1 = v1.complex_matrix_value ();
   Matrix m2 = v2.matrix_value ();
@@ -59,7 +60,8 @@
 
 DEFBINOP (div, complex_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   ComplexMatrix ret = xdiv (v1.complex_matrix_value (),
@@ -77,7 +79,8 @@
 
 DEFBINOP (ldiv, complex_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (),
@@ -100,7 +103,8 @@
 
 DEFBINOP (el_ldiv, complex_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   return quotient (v2.array_value (), v1.complex_array_value ());
 }
--- a/libinterp/operators/op-cm-s.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cm-s.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -46,7 +46,8 @@
 
 DEFBINOP (div, complex_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_scalar&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
 
@@ -60,7 +61,8 @@
 
 DEFBINOP (ldiv, complex_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_scalar&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   ComplexMatrix m1 = v1.complex_matrix_value ();
   Matrix m2 = v2.matrix_value ();
@@ -83,7 +85,8 @@
 
 DEFBINOP (el_div, complex_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_scalar&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
 
@@ -97,7 +100,8 @@
 
 DEFBINOP (el_ldiv, complex_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_scalar&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   return x_el_div (v2.double_value (), v1.complex_array_value ());
 }
--- a/libinterp/operators/op-cm-scm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cm-scm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -48,8 +48,8 @@
 
 DEFBINOP (div, complex_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -79,8 +79,8 @@
 
 DEFBINOP (ldiv, complex_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (),
@@ -105,8 +105,8 @@
 
 DEFBINOP (el_pow, complex_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value
          (elem_xpow (SparseComplexMatrix (v1.complex_matrix_value ()),
@@ -115,8 +115,8 @@
 
 DEFBINOP (el_ldiv, sparse_complex_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value (quotient (v2.sparse_complex_matrix_value (),
                                  v1.complex_matrix_value ()));
@@ -127,8 +127,8 @@
 
 DEFCATOP (cm_scm, complex_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (octave_complex_matrix&,
-                   const octave_sparse_complex_matrix&);
+  octave_complex_matrix& v1 = dynamic_cast<octave_complex_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
   SparseComplexMatrix tmp (v1.complex_matrix_value ());
   return octave_value (tmp. concat (v2.sparse_complex_matrix_value (),
                                     ra_idx));
@@ -137,7 +137,7 @@
 DEFCONV (sparse_complex_matrix_conv, complex_matrix,
          sparse_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_complex_matrix&);
+  const octave_complex_matrix& v = dynamic_cast<const octave_complex_matrix&> (a);
   return new octave_sparse_complex_matrix
          (SparseComplexMatrix (v.complex_matrix_value ()));
 }
--- a/libinterp/operators/op-cm-sm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cm-sm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -48,7 +48,8 @@
 
 DEFBINOP (div, complex_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&, const octave_sparse_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -78,8 +79,8 @@
 
 DEFBINOP (ldiv, complex_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&,
-                   const octave_sparse_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (),
@@ -101,8 +102,8 @@
 
 DEFBINOP (el_pow, complex_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&,
-                   const octave_sparse_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   return octave_value
          (elem_xpow (SparseComplexMatrix (v1.complex_matrix_value ()),
@@ -111,8 +112,8 @@
 
 DEFBINOP (el_ldiv, complex_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_matrix&,
-                   const octave_sparse_matrix&);
+  const octave_complex_matrix& v1 = dynamic_cast<const octave_complex_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
   return octave_value
          (quotient (v2.sparse_matrix_value (), v1.complex_matrix_value ()));
 }
@@ -122,7 +123,8 @@
 
 DEFCATOP (cm_sm, complex_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (octave_complex_matrix&, const octave_sparse_matrix&);
+  octave_complex_matrix& v1 = dynamic_cast<octave_complex_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
   SparseComplexMatrix tmp (v1.complex_matrix_value ());
   return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
 }
--- a/libinterp/operators/op-cs-cm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cs-cm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -42,7 +42,8 @@
 
 DEFBINOP (div, complex, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_complex_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   ComplexMatrix m1 = v1.complex_matrix_value ();
   ComplexMatrix m2 = v2.complex_matrix_value ();
@@ -58,7 +59,8 @@
 
 DEFBINOP (ldiv, complex, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_complex_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   Complex d = v1.complex_value ();
 
@@ -89,7 +91,8 @@
 
 DEFBINOP (el_ldiv, complex, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_complex_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   Complex d = v1.complex_value ();
 
@@ -109,7 +112,7 @@
 
 DEFCONV (complex_matrix_conv, complex, complex_matrix)
 {
-  CAST_CONV_ARG (const octave_complex&);
+  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
 
   return new octave_complex_matrix (v.complex_matrix_value ());
 }
--- a/libinterp/operators/op-cs-cs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cs-cs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -42,7 +42,7 @@
 
 DEFUNOP (not, complex)
 {
-  CAST_UNOP_ARG (const octave_complex&);
+  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
   Complex x = v.complex_value ();
   if (xisnan (x))
     err_nan_to_logical_conversion ();
@@ -56,7 +56,7 @@
 
 DEFUNOP (hermitian, complex)
 {
-  CAST_UNOP_ARG (const octave_complex&);
+  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
 
   return octave_value (conj (v.complex_value ()));
 }
@@ -72,7 +72,8 @@
 
 DEFBINOP (div, complex, complex)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v2.complex_value ();
 
@@ -86,7 +87,8 @@
 
 DEFBINOP (ldiv, complex, complex)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v1.complex_value ();
 
@@ -107,7 +109,8 @@
 
 DEFBINOP (el_div, complex, complex)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v2.complex_value ();
 
@@ -121,7 +124,8 @@
 
 DEFBINOP (el_ldiv, complex, complex)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v1.complex_value ();
 
@@ -133,14 +137,16 @@
 
 DEFBINOP (el_and, complex, complex)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   return v1.complex_value () != 0.0 && v2.complex_value () != 0.0;
 }
 
 DEFBINOP (el_or, complex, complex)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_complex&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   return v1.complex_value () != 0.0 || v2.complex_value () != 0.0;
 }
@@ -149,7 +155,7 @@
 
 CONVDECL (complex_to_float_complex)
 {
-  CAST_CONV_ARG (const octave_complex&);
+  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
 
   return new octave_float_complex_matrix (FloatComplexMatrix (1, 1,
                                           static_cast<FloatComplex>
--- a/libinterp/operators/op-cs-m.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cs-m.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -48,7 +48,8 @@
 
 DEFBINOP (div, complex, matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   ComplexMatrix m1 = v1.complex_matrix_value ();
   Matrix m2 = v2.matrix_value ();
@@ -64,7 +65,8 @@
 
 DEFBINOP (ldiv, complex, matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   Complex d = v1.complex_value ();
 
@@ -87,7 +89,8 @@
 
 DEFBINOP (el_ldiv, complex, matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   Complex d = v1.complex_value ();
 
--- a/libinterp/operators/op-cs-s.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cs-s.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -43,7 +43,8 @@
 
 DEFBINOP (div, complex, scalar)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
 
@@ -57,7 +58,8 @@
 
 DEFBINOP (ldiv, complex, scalar)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   Complex d = v1.complex_value ();
 
@@ -78,7 +80,8 @@
 
 DEFBINOP (el_div, complex, scalar)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
 
@@ -92,7 +95,8 @@
 
 DEFBINOP (el_ldiv, complex, scalar)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   Complex d = v1.complex_value ();
 
@@ -104,14 +108,16 @@
 
 DEFBINOP (el_and, complex, scalar)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   return v1.complex_value () != 0.0 && v2.double_value ();
 }
 
 DEFBINOP (el_or, complex, scalar)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_scalar&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   return v1.complex_value () != 0.0 || v2.double_value ();
 }
--- a/libinterp/operators/op-cs-scm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cs-scm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -46,7 +46,8 @@
 
 DEFBINOP (div, complex, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_complex_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -70,14 +71,15 @@
 
 DEFBINOP (pow, complex, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&,
-                   const octave_sparse_complex_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
   return xpow (v1.complex_value (), v2.complex_matrix_value ());
 }
 
 DEFBINOP (ldiv, complex, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_complex_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   Complex d = v1.complex_value ();
 
@@ -101,7 +103,8 @@
 
 DEFBINOP (el_ldiv, complex, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_complex_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   Complex d = v1.complex_value ();
   octave_value retval;
@@ -119,7 +122,8 @@
 
 DEFCATOP (cs_scm, complex, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (octave_complex&, const octave_sparse_complex_matrix&);
+  octave_complex& v1 = dynamic_cast<octave_complex&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
   SparseComplexMatrix tmp (1, 1, v1.complex_value ());
   return octave_value (tmp. concat (v2.sparse_complex_matrix_value (),
                                     ra_idx));
@@ -127,7 +131,7 @@
 
 DEFCONV (sparse_complex_matrix_conv, complex, sparse_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_complex&);
+  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
 
   return new octave_sparse_complex_matrix
          (SparseComplexMatrix (v.complex_matrix_value ()));
--- a/libinterp/operators/op-cs-sm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-cs-sm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -48,7 +48,8 @@
 
 DEFBINOP (div, complex, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -72,13 +73,15 @@
 
 DEFBINOP (pow, complex, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
   return xpow (v1.complex_value (), v2.matrix_value ());
 }
 
 DEFBINOP (ldiv, complex, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   Complex d = v1.complex_value ();
   octave_value retval;
@@ -104,7 +107,8 @@
 
 DEFBINOP (el_ldiv, complex, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex&, const octave_sparse_matrix&);
+  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   Complex d = v1.complex_value ();
   octave_value retval;
@@ -122,14 +126,15 @@
 
 DEFCATOP (cs_sm, sparse_matrix, complex)
 {
-  CAST_BINOP_ARGS (octave_complex&, const octave_sparse_matrix&);
+  octave_complex& v1 = dynamic_cast<octave_complex&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
   SparseComplexMatrix tmp (1, 1, v1.complex_value ());
   return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
 }
 
 DEFCONV (sparse_matrix_conv, complex, sparse_matrix)
 {
-  CAST_CONV_ARG (const octave_complex&);
+  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
 
   return new octave_sparse_matrix
          (SparseMatrix (v.matrix_value ()));
--- a/libinterp/operators/op-dm-dm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-dm-dm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -42,7 +42,7 @@
 
 DEFUNOP (transpose, diag_matrix)
 {
-  CAST_UNOP_ARG (const octave_diag_matrix&);
+  const octave_diag_matrix& v = dynamic_cast<const octave_diag_matrix&> (a);
   return octave_value (v.diag_matrix_value ().transpose ());
 }
 
@@ -54,7 +54,8 @@
 
 DEFBINOP (div, diag_matrix, diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_diag_matrix&);
+  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_diag_matrix& v2 = dynamic_cast<const octave_diag_matrix&> (a2);
 
   return xdiv (v1.diag_matrix_value (),
                v2.diag_matrix_value ());
@@ -62,7 +63,8 @@
 
 DEFBINOP (ldiv, diag_matrix, diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_diag_matrix&);
+  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_diag_matrix& v2 = dynamic_cast<const octave_diag_matrix&> (a2);
 
   return xleftdiv (v1.diag_matrix_value (),
                    v2.diag_matrix_value ());
@@ -70,14 +72,14 @@
 
 CONVDECL (diag_matrix_to_matrix)
 {
-  CAST_CONV_ARG (const octave_diag_matrix&);
+  const octave_diag_matrix& v = dynamic_cast<const octave_diag_matrix&> (a);
 
   return new octave_matrix (v.matrix_value ());
 }
 
 CONVDECL (diag_matrix_to_float_diag_matrix)
 {
-  CAST_CONV_ARG (const octave_diag_matrix&);
+  const octave_diag_matrix& v = dynamic_cast<const octave_diag_matrix&> (a);
 
   return new octave_float_diag_matrix (v.float_diag_matrix_value ());
 }
--- a/libinterp/operators/op-dm-scm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-dm-scm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -50,8 +50,8 @@
 
 DEFBINOP (mul_dm_scm, diag_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_diag_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -75,8 +75,8 @@
 
 DEFBINOP (mul_cdm_sm, complex_diag_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
-                   const octave_sparse_matrix&);
+  const octave_complex_diag_matrix& v1 = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -100,8 +100,8 @@
 
 DEFBINOP (mul_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_complex_diag_matrix& v1 = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -125,8 +125,8 @@
 
 DEFBINOP (ldiv_dm_scm, diag_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_diag_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   MatrixType typ = v2.matrix_type ();
   return xleftdiv (v1.diag_matrix_value (), v2.sparse_complex_matrix_value (),
@@ -135,8 +135,8 @@
 
 DEFBINOP (ldiv_cdm_sm, complex_diag_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
-                   const octave_sparse_matrix&);
+  const octave_complex_diag_matrix& v1 = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   MatrixType typ = v2.matrix_type ();
   return xleftdiv (v1.complex_diag_matrix_value (), v2.sparse_matrix_value (),
@@ -145,8 +145,8 @@
 
 DEFBINOP (ldiv_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_complex_diag_matrix& v1 = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   MatrixType typ = v2.matrix_type ();
   return xleftdiv (v1.complex_diag_matrix_value (),
@@ -156,8 +156,8 @@
 
 DEFBINOP (add_dm_scm, diag_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_diag_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -173,8 +173,8 @@
 
 DEFBINOP (add_cdm_sm, complex_diag_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
-                   const octave_sparse_matrix&);
+  const octave_complex_diag_matrix& v1 = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -190,8 +190,8 @@
 
 DEFBINOP (add_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_complex_diag_matrix& v1 = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -207,8 +207,8 @@
 
 DEFBINOP (sub_dm_scm, diag_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_diag_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -224,8 +224,8 @@
 
 DEFBINOP (sub_cdm_sm, complex_diag_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
-                   const octave_sparse_matrix&);
+  const octave_complex_diag_matrix& v1 = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -241,8 +241,8 @@
 
 DEFBINOP (sub_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_complex_diag_matrix& v1 = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -260,8 +260,8 @@
 
 DEFBINOP (mul_scm_dm, sparse_complex_matrix, diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_diag_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_diag_matrix& v2 = dynamic_cast<const octave_diag_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     // If v1 is a scalar in disguise, return a diagonal matrix rather than
@@ -285,8 +285,8 @@
 
 DEFBINOP (mul_sm_cdm, sparse_matrix, complex_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&,
-                   const octave_complex_diag_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex_diag_matrix& v2 = dynamic_cast<const octave_complex_diag_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     // If v1 is a scalar in disguise, return a diagonal matrix rather than
@@ -310,8 +310,8 @@
 
 DEFBINOP (mul_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_complex_diag_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex_diag_matrix& v2 = dynamic_cast<const octave_complex_diag_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     // If v1 is a scalar in disguise, return a diagonal matrix rather than
@@ -342,8 +342,8 @@
 
 DEFBINOP (div_scm_dm, sparse_complex_matrix, diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_diag_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_diag_matrix& v2 = dynamic_cast<const octave_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -364,8 +364,8 @@
 
 DEFBINOP (div_sm_cdm, sparse_matrix, complex_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&,
-                   const octave_complex_diag_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex_diag_matrix& v2 = dynamic_cast<const octave_complex_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -386,8 +386,8 @@
 
 DEFBINOP (div_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_complex_diag_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex_diag_matrix& v2 = dynamic_cast<const octave_complex_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -408,8 +408,8 @@
 
 DEFBINOP (add_sm_cdm, sparse_matrix, complex_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&,
-                   const octave_complex_diag_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex_diag_matrix& v2 = dynamic_cast<const octave_complex_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -425,8 +425,8 @@
 
 DEFBINOP (add_scm_dm, sparse_complex_matrix, diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_diag_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_diag_matrix& v2 = dynamic_cast<const octave_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -442,8 +442,8 @@
 
 DEFBINOP (add_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_complex_diag_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex_diag_matrix& v2 = dynamic_cast<const octave_complex_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -459,8 +459,8 @@
 
 DEFBINOP (sub_sm_cdm, sparse_matrix, complex_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&,
-                   const octave_complex_diag_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex_diag_matrix& v2 = dynamic_cast<const octave_complex_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -476,8 +476,8 @@
 
 DEFBINOP (sub_scm_dm, sparse_complex_matrix, diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_diag_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_diag_matrix& v2 = dynamic_cast<const octave_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -493,8 +493,8 @@
 
 DEFBINOP (sub_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_complex_diag_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex_diag_matrix& v2 = dynamic_cast<const octave_complex_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
--- a/libinterp/operators/op-dm-sm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-dm-sm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -39,7 +39,8 @@
 
 DEFBINOP (mul_dm_sm, diag_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_sparse_matrix&);
+  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -62,7 +63,8 @@
 
 DEFBINOP (ldiv_dm_sm, diag_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_sparse_matrix&);
+  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   MatrixType typ = v2.matrix_type ();
   return xleftdiv (v1.diag_matrix_value (), v2.sparse_matrix_value (), typ);
@@ -70,7 +72,8 @@
 
 DEFBINOP (add_dm_sm, diag_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_sparse_matrix&);
+  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -86,7 +89,8 @@
 
 DEFBINOP (sub_dm_sm, diag_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_sparse_matrix&);
+  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     // If v2 is a scalar in disguise, return a diagonal matrix rather than
@@ -104,7 +108,8 @@
 
 DEFBINOP (mul_sm_dm, sparse_matrix, diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_diag_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_diag_matrix& v2 = dynamic_cast<const octave_diag_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     // If v1 is a scalar in disguise, return a diagonal matrix rather than
@@ -127,7 +132,8 @@
 
 DEFBINOP (div_sm_dm, sparse_matrix, diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_diag_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_diag_matrix& v2 = dynamic_cast<const octave_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -147,7 +153,8 @@
 
 DEFBINOP (add_sm_dm, sparse_matrix, diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_diag_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_diag_matrix& v2 = dynamic_cast<const octave_diag_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     // If v1 is a scalar in disguise, return a diagonal matrix rather than
@@ -163,7 +170,8 @@
 
 DEFBINOP (sub_sm_dm, sparse_matrix, diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_diag_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_diag_matrix& v2 = dynamic_cast<const octave_diag_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     // If v1 is a scalar in disguise, return a diagonal matrix rather than
--- a/libinterp/operators/op-dm-template.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-dm-template.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -61,7 +61,8 @@
 #ifdef DEFINEDIV
 DEFBINOP (div, LMATRIX, RMATRIX)
 {
-  CAST_BINOP_ARGS (const OCTAVE_LMATRIX&, const OCTAVE_RMATRIX&);
+  const OCTAVE_LMATRIX& v1 = dynamic_cast<const OCTAVE_LMATRIX&> (a1);
+  const OCTAVE_RMATRIX& v2 = dynamic_cast<const OCTAVE_RMATRIX&> (a2);
 
   return xdiv (v1.LDMATRIX_VALUE (), v2.RMATRIX_VALUE ());
 }
@@ -70,7 +71,8 @@
 #ifdef DEFINELDIV
 DEFBINOP (ldiv, LMATRIX, RMATRIX)
 {
-  CAST_BINOP_ARGS (const OCTAVE_LMATRIX&, const OCTAVE_RMATRIX&);
+  const OCTAVE_LMATRIX& v1 = dynamic_cast<const OCTAVE_LMATRIX&> (a1);
+  const OCTAVE_RMATRIX& v2 = dynamic_cast<const OCTAVE_RMATRIX&> (a2);
 
   return xleftdiv (v1.LMATRIX_VALUE (), v2.RDMATRIX_VALUE ());
 }
--- a/libinterp/operators/op-dms-template.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-dms-template.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -60,21 +60,24 @@
 
 DEFBINOP (dmsdiv, MATRIX, SCALAR)
 {
-  CAST_BINOP_ARGS (const OCTAVE_MATRIX&, const OCTAVE_SCALAR&);
+  const OCTAVE_MATRIX& v1 = dynamic_cast<const OCTAVE_MATRIX&> (a1);
+  const OCTAVE_SCALAR& v2 = dynamic_cast<const OCTAVE_SCALAR&> (a2);
 
   return v1.MATRIX_VALUE () / gripe_if_zero (v2.SCALAR_VALUE ());
 }
 
 DEFBINOP (sdmldiv, SCALAR, MATRIX)
 {
-  CAST_BINOP_ARGS (const OCTAVE_SCALAR&, const OCTAVE_MATRIX&);
+  const OCTAVE_SCALAR& v1 = dynamic_cast<const OCTAVE_SCALAR&> (a1);
+  const OCTAVE_MATRIX& v2 = dynamic_cast<const OCTAVE_MATRIX&> (a2);
 
   return v2.MATRIX_VALUE () / gripe_if_zero (v1.SCALAR_VALUE ());
 }
 
 DEFBINOP (dmspow, MATRIX, SCALAR)
 {
-  CAST_BINOP_ARGS (const OCTAVE_MATRIX&, const OCTAVE_SCALAR&);
+  const OCTAVE_MATRIX& v1 = dynamic_cast<const OCTAVE_MATRIX&> (a1);
+  const OCTAVE_SCALAR& v2 = dynamic_cast<const OCTAVE_SCALAR&> (a2);
 
   return xpow (v1.MATRIX_VALUE (), v2.SCALAR_VALUE ());
 }
--- a/libinterp/operators/op-fcdm-fcdm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fcdm-fcdm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -42,13 +42,13 @@
 
 DEFUNOP (transpose, float_complex_diag_matrix)
 {
-  CAST_UNOP_ARG (const octave_float_complex_diag_matrix&);
+  const octave_float_complex_diag_matrix& v = dynamic_cast<const octave_float_complex_diag_matrix&> (a);
   return octave_value (v.float_complex_diag_matrix_value ().transpose ());
 }
 
 DEFUNOP (hermitian, float_complex_diag_matrix)
 {
-  CAST_UNOP_ARG (const octave_float_complex_diag_matrix&);
+  const octave_float_complex_diag_matrix& v = dynamic_cast<const octave_float_complex_diag_matrix&> (a);
   return octave_value (v.float_complex_diag_matrix_value ().hermitian ());
 }
 
@@ -60,8 +60,8 @@
 
 DEFBINOP (div, float_complex_diag_matrix, float_complex_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_diag_matrix&,
-                   const octave_float_complex_diag_matrix&);
+  const octave_float_complex_diag_matrix& v1 = dynamic_cast<const octave_float_complex_diag_matrix&> (a1);
+  const octave_float_complex_diag_matrix& v2 = dynamic_cast<const octave_float_complex_diag_matrix&> (a2);
 
   return xdiv (v1.float_complex_diag_matrix_value (),
                v2.float_complex_diag_matrix_value ());
@@ -69,8 +69,8 @@
 
 DEFBINOP (ldiv, float_complex_diag_matrix, float_complex_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_diag_matrix&,
-                   const octave_float_complex_diag_matrix&);
+  const octave_float_complex_diag_matrix& v1 = dynamic_cast<const octave_float_complex_diag_matrix&> (a1);
+  const octave_float_complex_diag_matrix& v2 = dynamic_cast<const octave_float_complex_diag_matrix&> (a2);
 
   return xleftdiv (v1.float_complex_diag_matrix_value (),
                    v2.float_complex_diag_matrix_value ());
@@ -78,14 +78,14 @@
 
 CONVDECL (float_complex_diag_matrix_to_float_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_float_complex_diag_matrix&);
+  const octave_float_complex_diag_matrix& v = dynamic_cast<const octave_float_complex_diag_matrix&> (a);
 
   return new octave_float_complex_matrix (v.float_complex_matrix_value ());
 }
 
 CONVDECL (float_complex_diag_matrix_to_complex_diag_matrix)
 {
-  CAST_CONV_ARG (const octave_float_complex_diag_matrix&);
+  const octave_float_complex_diag_matrix& v = dynamic_cast<const octave_float_complex_diag_matrix&> (a);
 
   return new octave_complex_diag_matrix (v.complex_diag_matrix_value ());
 }
--- a/libinterp/operators/op-fcm-fcm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fcm-fcm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -43,7 +43,7 @@
 
 DEFUNOP (transpose, float_complex_matrix)
 {
-  CAST_UNOP_ARG (const octave_float_complex_matrix&);
+  const octave_float_complex_matrix& v = dynamic_cast<const octave_float_complex_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -53,7 +53,7 @@
 
 DEFUNOP (hermitian, float_complex_matrix)
 {
-  CAST_UNOP_ARG (const octave_float_complex_matrix&);
+  const octave_float_complex_matrix& v = dynamic_cast<const octave_float_complex_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("complex-conjugate transpose not defined for N-D objects");
@@ -76,8 +76,8 @@
 
 DEFBINOP (div, float_complex_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   FloatComplexMatrix ret = xdiv (v1.float_complex_matrix_value (),
@@ -94,8 +94,8 @@
 
 DEFBINOP (ldiv, float_complex_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (),
@@ -107,8 +107,8 @@
 
 DEFBINOP (trans_mul, float_complex_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
   return octave_value(xgemm (v1.float_complex_matrix_value (),
                              v2.float_complex_matrix_value (),
                              blas_trans, blas_no_trans));
@@ -116,8 +116,8 @@
 
 DEFBINOP (mul_trans, float_complex_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
   return octave_value(xgemm (v1.float_complex_matrix_value (),
                              v2.float_complex_matrix_value (),
                              blas_no_trans, blas_trans));
@@ -125,8 +125,8 @@
 
 DEFBINOP (herm_mul, float_complex_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
   return octave_value(xgemm (v1.float_complex_matrix_value (),
                              v2.float_complex_matrix_value (),
                              blas_conj_trans, blas_no_trans));
@@ -134,8 +134,8 @@
 
 DEFBINOP (mul_herm, float_complex_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
   return octave_value(xgemm (v1.float_complex_matrix_value (),
                              v2.float_complex_matrix_value (),
                              blas_no_trans, blas_conj_trans));
@@ -143,8 +143,8 @@
 
 DEFBINOP (trans_ldiv, float_complex_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (),
@@ -157,8 +157,8 @@
 
 DEFBINOP (herm_ldiv, float_complex_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (),
@@ -191,8 +191,8 @@
 
 DEFBINOP (el_ldiv, float_complex_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
 
   return octave_value (quotient (v2.float_complex_array_value (),
                                  v1.float_complex_array_value ()));
@@ -234,7 +234,7 @@
 
 CONVDECL (float_complex_matrix_to_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_float_complex_matrix&);
+  const octave_float_complex_matrix& v = dynamic_cast<const octave_float_complex_matrix&> (a);
 
   return
     new octave_complex_matrix (ComplexNDArray (v.float_complex_array_value ()));
--- a/libinterp/operators/op-fcm-fcs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fcm-fcs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -47,8 +47,8 @@
 
 DEFBINOP (div, float_complex_matrix, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   FloatComplex d = v2.float_complex_value ();
 
@@ -62,8 +62,8 @@
 
 DEFBINOP (ldiv, float_complex_matrix, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
   FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
@@ -92,8 +92,8 @@
 
 DEFBINOP (el_div, float_complex_matrix, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   FloatComplex d = v2.float_complex_value ();
 
@@ -108,8 +108,8 @@
 
 DEFBINOP (el_ldiv, float_complex_matrix, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_complex&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   return x_el_div (v2.float_complex_value (), v1.float_complex_array_value ());
 }
--- a/libinterp/operators/op-fcm-fm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fcm-fm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -52,8 +52,8 @@
 
 DEFBINOP (mul_trans, float_complex_matrix, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
 
   FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
   FloatMatrix m2 = v2.float_matrix_value ();
@@ -64,8 +64,8 @@
 
 DEFBINOP (div, float_complex_matrix, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   FloatComplexMatrix ret = xdiv (v1.float_complex_matrix_value (),
@@ -83,8 +83,8 @@
 
 DEFBINOP (ldiv, float_complex_matrix, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (),
@@ -116,8 +116,8 @@
 
 DEFBINOP (el_ldiv, float_complex_matrix, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_matrix&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
 
   return quotient (v2.float_array_value (), v1.float_complex_array_value ());
 }
--- a/libinterp/operators/op-fcm-fs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fcm-fs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -50,8 +50,8 @@
 
 DEFBINOP (div, float_complex_matrix, float)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_scalar&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   float d = v2.float_value ();
 
@@ -65,8 +65,8 @@
 
 DEFBINOP (ldiv, float_complex_matrix, float)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_scalar&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
   FloatMatrix m2 = v2.float_matrix_value ();
@@ -96,8 +96,8 @@
 
 DEFBINOP (el_div, float_complex_matrix, float)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_scalar&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   float d = v2.float_value ();
 
@@ -112,8 +112,8 @@
 
 DEFBINOP (el_ldiv, float_complex_matrix, float)
 {
-  CAST_BINOP_ARGS (const octave_float_complex_matrix&,
-                   const octave_float_scalar&);
+  const octave_float_complex_matrix& v1 = dynamic_cast<const octave_float_complex_matrix&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   return x_el_div (v2.float_value (), v1.float_complex_array_value ());
 }
--- a/libinterp/operators/op-fcn.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fcn.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -34,14 +34,16 @@
 
 DEFBINOP (eq, fcn_handle, fcn_handle)
 {
-  CAST_BINOP_ARGS (const octave_fcn_handle&, const octave_fcn_handle&);
+  const octave_fcn_handle& v1 = dynamic_cast<const octave_fcn_handle&> (a1);
+  const octave_fcn_handle& v2 = dynamic_cast<const octave_fcn_handle&> (a2);
 
   return v1.is_equal_to (v2);
 }
 
 DEFBINOP (ne, fcn_handle, fcn_handle)
 {
-  CAST_BINOP_ARGS (const octave_fcn_handle&, const octave_fcn_handle&);
+  const octave_fcn_handle& v1 = dynamic_cast<const octave_fcn_handle&> (a1);
+  const octave_fcn_handle& v2 = dynamic_cast<const octave_fcn_handle&> (a2);
 
   return ! v1.is_equal_to (v2);
 }
--- a/libinterp/operators/op-fcs-fcm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fcs-fcm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -47,8 +47,8 @@
 
 DEFBINOP (div, float_complex, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&,
-                   const octave_float_complex_matrix&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
 
   FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
   FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
@@ -64,8 +64,8 @@
 
 DEFBINOP (ldiv, float_complex, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&,
-                   const octave_float_complex_matrix&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
 
   FloatComplex d = v1.float_complex_value ();
 
@@ -97,8 +97,8 @@
 
 DEFBINOP (el_ldiv, float_complex, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&,
-                   const octave_float_complex_matrix&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
 
   FloatComplex d = v1.float_complex_value ();
 
@@ -124,7 +124,7 @@
 
 DEFCONV (float_complex_matrix_conv, float_complex, float_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_float_complex&);
+  const octave_float_complex& v = dynamic_cast<const octave_float_complex&> (a);
 
   return new octave_float_complex_matrix (v.float_complex_matrix_value ());
 }
--- a/libinterp/operators/op-fcs-fcs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fcs-fcs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -40,7 +40,7 @@
 
 DEFUNOP (not, float_complex)
 {
-  CAST_UNOP_ARG (const octave_float_complex&);
+  const octave_float_complex& v = dynamic_cast<const octave_float_complex&> (a);
   FloatComplex x = v.float_complex_value ();
   if (xisnan (x))
     err_nan_to_logical_conversion ();
@@ -54,7 +54,7 @@
 
 DEFUNOP (hermitian, float_complex)
 {
-  CAST_UNOP_ARG (const octave_float_complex&);
+  const octave_float_complex& v = dynamic_cast<const octave_float_complex&> (a);
 
   return octave_value (conj (v.float_complex_value ()));
 }
@@ -70,7 +70,8 @@
 
 DEFBINOP (div, float_complex, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   FloatComplex d = v2.float_complex_value ();
 
@@ -84,7 +85,8 @@
 
 DEFBINOP (ldiv, float_complex, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   FloatComplex d = v1.float_complex_value ();
 
@@ -105,7 +107,8 @@
 
 DEFBINOP (el_div, float_complex, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   FloatComplex d = v2.float_complex_value ();
 
@@ -119,7 +122,8 @@
 
 DEFBINOP (el_ldiv, float_complex, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   FloatComplex d = v1.float_complex_value ();
 
@@ -131,7 +135,8 @@
 
 DEFBINOP (el_and, float_complex, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   return (v1.float_complex_value () != 0.0f
           && v2.float_complex_value () != 0.0f);
@@ -139,7 +144,8 @@
 
 DEFBINOP (el_or, float_complex, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_complex&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   return (v1.float_complex_value () != 0.0f
           || v2.float_complex_value () != 0.0f);
@@ -156,7 +162,7 @@
 
 CONVDECL (float_complex_to_complex)
 {
-  CAST_CONV_ARG (const octave_float_complex&);
+  const octave_float_complex& v = dynamic_cast<const octave_float_complex&> (a);
 
   return new octave_complex_matrix
                (ComplexMatrix (1, 1,
--- a/libinterp/operators/op-fcs-fm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fcs-fm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -49,7 +49,8 @@
 
 DEFBINOP (div, float_complex, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_matrix&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
 
   FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
   FloatMatrix m2 = v2.float_matrix_value ();
@@ -65,7 +66,8 @@
 
 DEFBINOP (ldiv, float_complex, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_matrix&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
 
   FloatComplex d = v1.float_complex_value ();
 
@@ -97,7 +99,8 @@
 
 DEFBINOP (el_ldiv, float_complex, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_matrix&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
 
   FloatComplex d = v1.float_complex_value ();
 
--- a/libinterp/operators/op-fcs-fs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fcs-fs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -46,7 +46,8 @@
 
 DEFBINOP (div, float_complex, float)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   float d = v2.float_value ();
 
@@ -60,7 +61,8 @@
 
 DEFBINOP (ldiv, float_complex, float)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   FloatComplex d = v1.float_complex_value ();
 
@@ -81,7 +83,8 @@
 
 DEFBINOP (el_div, float_complex, float)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   float d = v2.float_value ();
 
@@ -95,7 +98,8 @@
 
 DEFBINOP (el_ldiv, float_complex, float)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   FloatComplex d = v1.float_complex_value ();
 
@@ -107,14 +111,16 @@
 
 DEFBINOP (el_and, float_complex, float)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   return (v1.float_complex_value () != 0.0f && v2.float_value ());
 }
 
 DEFBINOP (el_or, float_complex, float)
 {
-  CAST_BINOP_ARGS (const octave_float_complex&, const octave_float_scalar&);
+  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   return (v1.float_complex_value () != 0.0f || v2.float_value ());
 }
--- a/libinterp/operators/op-fdm-fdm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fdm-fdm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -42,7 +42,7 @@
 
 DEFUNOP (transpose, float_diag_matrix)
 {
-  CAST_UNOP_ARG (const octave_float_diag_matrix&);
+  const octave_float_diag_matrix& v = dynamic_cast<const octave_float_diag_matrix&> (a);
   return octave_value (v.float_diag_matrix_value ().transpose ());
 }
 
@@ -54,8 +54,8 @@
 
 DEFBINOP (div, float_diag_matrix, float_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_diag_matrix&,
-                   const octave_float_diag_matrix&);
+  const octave_float_diag_matrix& v1 = dynamic_cast<const octave_float_diag_matrix&> (a1);
+  const octave_float_diag_matrix& v2 = dynamic_cast<const octave_float_diag_matrix&> (a2);
 
   return xdiv (v1.float_diag_matrix_value (),
                v2.float_diag_matrix_value ());
@@ -63,8 +63,8 @@
 
 DEFBINOP (ldiv, float_diag_matrix, float_diag_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_diag_matrix&,
-                   const octave_float_diag_matrix&);
+  const octave_float_diag_matrix& v1 = dynamic_cast<const octave_float_diag_matrix&> (a1);
+  const octave_float_diag_matrix& v2 = dynamic_cast<const octave_float_diag_matrix&> (a2);
 
   return xleftdiv (v1.float_diag_matrix_value (),
                    v2.float_diag_matrix_value ());
@@ -72,14 +72,14 @@
 
 CONVDECL (float_diag_matrix_to_diag_matrix)
 {
-  CAST_CONV_ARG (const octave_float_diag_matrix&);
+  const octave_float_diag_matrix& v = dynamic_cast<const octave_float_diag_matrix&> (a);
 
   return new octave_diag_matrix (v.diag_matrix_value ());
 }
 
 CONVDECL (float_diag_matrix_to_float_matrix)
 {
-  CAST_CONV_ARG (const octave_float_diag_matrix&);
+  const octave_float_diag_matrix& v = dynamic_cast<const octave_float_diag_matrix&> (a);
 
   return new octave_float_matrix (v.float_matrix_value ());
 }
--- a/libinterp/operators/op-fm-fcm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fm-fcm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -52,8 +52,8 @@
 
 DEFBINOP (trans_mul, float_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
 
   FloatMatrix m1 = v1.float_matrix_value ();
   FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
@@ -64,8 +64,8 @@
 
 DEFBINOP (div, float_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   FloatComplexMatrix ret = xdiv (v1.float_matrix_value (),
@@ -82,8 +82,8 @@
 
 DEFBINOP (ldiv, float_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatComplexMatrix ret = xleftdiv (v1.float_matrix_value (),
@@ -95,8 +95,8 @@
 
 DEFBINOP (trans_ldiv, float_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatComplexMatrix ret = xleftdiv (v1.float_matrix_value (),
@@ -129,8 +129,8 @@
 
 DEFBINOP (el_ldiv, float_matrix, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&,
-                   const octave_float_complex_matrix&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
 
   return quotient (v2.float_complex_array_value (), v1.float_array_value ());
 }
@@ -151,7 +151,7 @@
 
 DEFCONV (float_complex_matrix_conv, float_matrix, float_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_float_matrix&);
+  const octave_float_matrix& v = dynamic_cast<const octave_float_matrix&> (a);
 
   return new octave_float_complex_matrix (FloatComplexNDArray
                                            (v.float_array_value ()));
--- a/libinterp/operators/op-fm-fcs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fm-fcs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -51,7 +51,8 @@
 
 DEFBINOP (div, float_matrix, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_complex&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   FloatComplex d = v2.float_complex_value ();
 
@@ -65,7 +66,8 @@
 
 DEFBINOP (ldiv, float_matrix, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_complex&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   FloatMatrix m1 = v1.float_matrix_value ();
   FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
@@ -95,7 +97,8 @@
 
 DEFBINOP (el_div, float_matrix, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_complex&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   FloatComplex d = v2.float_complex_value ();
 
@@ -110,7 +113,8 @@
 
 DEFBINOP (el_ldiv, float_matrix, flaot_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_complex&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   return x_el_div (v2.float_complex_value (), v1.float_array_value ());
 }
--- a/libinterp/operators/op-fm-fm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fm-fm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -43,7 +43,7 @@
 
 DEFUNOP (transpose, float_matrix)
 {
-  CAST_UNOP_ARG (const octave_float_matrix&);
+  const octave_float_matrix& v = dynamic_cast<const octave_float_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -64,7 +64,8 @@
 
 DEFBINOP (div, float_matrix, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_matrix&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   FloatMatrix ret = xdiv (v1.float_matrix_value (),
@@ -81,7 +82,8 @@
 
 DEFBINOP (ldiv, float_matrix, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_matrix&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatMatrix ret = xleftdiv (v1.float_matrix_value (),
@@ -93,7 +95,8 @@
 
 DEFBINOP (trans_mul, float_matrix, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_matrix&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
   return octave_value(xgemm (v1.float_matrix_value (),
                              v2.float_matrix_value (),
                              blas_trans, blas_no_trans));
@@ -101,7 +104,8 @@
 
 DEFBINOP (mul_trans, float_matrix, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_matrix&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
   return octave_value(xgemm (v1.float_matrix_value (),
                              v2.float_matrix_value (),
                              blas_no_trans, blas_trans));
@@ -109,7 +113,8 @@
 
 DEFBINOP (trans_ldiv, float_matrix, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_matrix&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatMatrix ret = xleftdiv (v1.float_matrix_value (),
@@ -141,7 +146,8 @@
 
 DEFBINOP (el_ldiv, float_matrix, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_matrix&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
 
   return octave_value (quotient (v2.float_array_value (),
                                  v1.float_array_value ()));
@@ -184,7 +190,7 @@
 
 CONVDECL (float_matrix_to_matrix)
 {
-  CAST_CONV_ARG (const octave_float_matrix&);
+  const octave_float_matrix& v = dynamic_cast<const octave_float_matrix&> (a);
 
   return new octave_matrix (v.array_value ());
 }
--- a/libinterp/operators/op-fm-fs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fm-fs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -43,7 +43,8 @@
 
 DEFBINOP (div, float_matrix, float)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_scalar&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   float d = v2.float_value ();
 
@@ -57,7 +58,8 @@
 
 DEFBINOP (ldiv, float_matrix, float)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_scalar&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   FloatMatrix m1 = v1.float_matrix_value ();
   FloatMatrix m2 = v2.float_matrix_value ();
@@ -86,7 +88,8 @@
 
 DEFBINOP (el_div, float_matrix, float)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_scalar&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   float d = v2.float_value ();
 
@@ -101,7 +104,8 @@
 
 DEFBINOP (el_ldiv, float_matrix, float)
 {
-  CAST_BINOP_ARGS (const octave_float_matrix&, const octave_float_scalar&);
+  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   return x_el_div (v2.float_value (), v1.float_array_value ());
 }
--- a/libinterp/operators/op-fs-fcm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fs-fcm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -53,8 +53,8 @@
 
 DEFBINOP (div, float_scalar, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&,
-                   const octave_float_complex_matrix&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
 
   FloatMatrix m1 = v1.float_matrix_value ();
   FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
@@ -70,8 +70,8 @@
 
 DEFBINOP (ldiv, float_scalar, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&,
-                   const octave_float_complex_matrix&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
 
   float d = v1.float_value ();
 
@@ -103,8 +103,8 @@
 
 DEFBINOP (el_ldiv, float_scalar, float_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&,
-                   const octave_float_complex_matrix&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_complex_matrix& v2 = dynamic_cast<const octave_float_complex_matrix&> (a2);
 
   float d = v1.float_value ();
 
@@ -130,7 +130,7 @@
 
 DEFCONV (float_complex_matrix_conv, float_scalar, float_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_float_scalar&);
+  const octave_float_scalar& v = dynamic_cast<const octave_float_scalar&> (a);
 
   return new octave_float_complex_matrix (FloatComplexMatrix
                                             (v.float_matrix_value ()));
--- a/libinterp/operators/op-fs-fcs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fs-fcs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -46,7 +46,8 @@
 
 DEFBINOP (div, float_scalar, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   FloatComplex d = v2.float_complex_value ();
 
@@ -60,7 +61,8 @@
 
 DEFBINOP (ldiv, float_scalar, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   float d = v1.float_value ();
 
@@ -81,7 +83,8 @@
 
 DEFBINOP (el_div, float_scalar, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   FloatComplex d = v2.float_complex_value ();
 
@@ -95,7 +98,8 @@
 
 DEFBINOP (el_ldiv, float_scalar, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   float d = v1.float_value ();
 
@@ -107,7 +111,8 @@
 
 DEFBINOP (el_and, float_scalar, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   return octave_value (v1.float_scalar_value ()
                        && (v2.float_complex_value () != 0.0f));
@@ -115,7 +120,8 @@
 
 DEFBINOP (el_or, float_scalar, float_complex)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_complex&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_complex& v2 = dynamic_cast<const octave_float_complex&> (a2);
 
   return octave_value (v1.float_scalar_value ()
                        || (v2.float_complex_value () != 0.0f));
--- a/libinterp/operators/op-fs-fm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fs-fm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -44,7 +44,8 @@
 
 DEFBINOP (div, float_scalar, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_matrix&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
 
   FloatMatrix m1 = v1.float_matrix_value ();
   FloatMatrix m2 = v2.float_matrix_value ();
@@ -60,7 +61,8 @@
 
 DEFBINOP (ldiv, float_scalar, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_matrix&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
 
   float d = v1.float_value ();
 
@@ -92,7 +94,8 @@
 
 DEFBINOP (el_ldiv, float_scalar, float_matrix)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_matrix&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_matrix& v2 = dynamic_cast<const octave_float_matrix&> (a2);
 
   float d = v1.float_value ();
 
@@ -116,7 +119,7 @@
 
 DEFCONV (matrix_conv, float_scalar, float_matrix)
 {
-  CAST_CONV_ARG (const octave_float_scalar&);
+  const octave_float_scalar& v = dynamic_cast<const octave_float_scalar&> (a);
 
   return new octave_float_matrix (v.float_matrix_value ());
 }
--- a/libinterp/operators/op-fs-fs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-fs-fs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -42,7 +42,7 @@
 
 DEFUNOP (not, float_scalar)
 {
-  CAST_UNOP_ARG (const octave_float_scalar&);
+  const octave_float_scalar& v = dynamic_cast<const octave_float_scalar&> (a);
   float x = v.float_value ();
   if (xisnan (x))
     err_nan_to_logical_conversion ();
@@ -66,7 +66,8 @@
 
 DEFBINOP (div, float_scalar, float_scalar)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_scalar&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   float d = v2.float_value ();
 
@@ -80,7 +81,8 @@
 
 DEFBINOP (ldiv, float_scalar, float_scalar)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_scalar&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   float d = v1.float_value ();
 
@@ -101,7 +103,8 @@
 
 DEFBINOP (el_div, float_scalar, float_scalar)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_scalar&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   float d = v2.float_value ();
 
@@ -115,7 +118,8 @@
 
 DEFBINOP (el_ldiv, float_scalar, float_scalar)
 {
-  CAST_BINOP_ARGS (const octave_float_scalar&, const octave_float_scalar&);
+  const octave_float_scalar& v1 = dynamic_cast<const octave_float_scalar&> (a1);
+  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
 
   float d = v1.float_value ();
 
@@ -135,7 +139,7 @@
 
 CONVDECL (float_to_scalar)
 {
-  CAST_CONV_ARG (const octave_float_scalar&);
+  const octave_float_scalar& v = dynamic_cast<const octave_float_scalar&> (a);
 
   return new octave_matrix (Matrix (1, 1,
                                     static_cast<double>(v.float_value ())));
--- a/libinterp/operators/op-int-conv.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-int-conv.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -49,7 +49,7 @@
 #define DEFINTCONVFN(name, tfrom, tto) \
   CONVDECL (name) \
   { \
-    CAST_CONV_ARG (const octave_ ## tfrom&); \
+    const octave_ ## tfrom& v = dynamic_cast<const octave_ ## tfrom&> (a); \
  \
     octave_ ## tto ## _matrix v2 = v.tto ## _array_value (); \
     return new octave_ ## tto ## _matrix (v2); \
--- a/libinterp/operators/op-int.h	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-int.h	Wed Apr 27 16:13:40 2016 -0400
@@ -29,35 +29,43 @@
 #include "bsxfun.h"
 
 #define DEFINTBINOP_OP(name, t1, t2, op, t3) \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    const octave_ ## t1& v1 = dynamic_cast<const octave_ ## t1&> (a1); \
+    const octave_ ## t2& v2 = dynamic_cast<const octave_ ## t2&> (a2); \
     octave_value retval = octave_value \
       (v1.t1 ## _value () op v2.t2 ## _value ()); \
     return retval; \
   }
 
 #define DEFINTNDBINOP_OP(name, t1, t2, e1, e2, op, t3) \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    const octave_ ## t1& v1 = dynamic_cast<const octave_ ## t1&> (a1); \
+    const octave_ ## t2& v2 = dynamic_cast<const octave_ ## t2&> (a2); \
     octave_value retval = octave_value \
       (v1.e1 ## _value () op v2.e2 ## _value ()); \
     return retval; \
   }
 
 #define DEFINTBINOP_FN(name, t1, t2, f, t3, op) \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    const octave_ ## t1& v1 = dynamic_cast<const octave_ ## t1&> (a1); \
+    const octave_ ## t2& v2 = dynamic_cast<const octave_ ## t2&> (a2); \
     octave_value retval = octave_value (f (v1.t1 ## _value (), v2.t2 ## _value ())); \
     return retval; \
   }
 
 #define DEFINTNDBINOP_FN(name, t1, t2, e1, e2, f, t3, op)       \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    const octave_ ## t1& v1 = dynamic_cast<const octave_ ## t1&> (a1); \
+    const octave_ ## t2& v2 = dynamic_cast<const octave_ ## t2&> (a2); \
     octave_value retval = octave_value (f (v1.e1 ## _value (), v2.e2 ## _value ())); \
     return retval; \
   }
@@ -164,7 +172,7 @@
   DEFUNOP_OP (s_uplus, TYPE ## _scalar, /* no-op */) \
   DEFUNOP (s_uminus, TYPE ## _scalar) \
   { \
-    CAST_UNOP_ARG (const octave_ ## TYPE ## _scalar &); \
+    const octave_ ## TYPE ## _scalar & v = dynamic_cast<const octave_ ## TYPE ## _scalar &> (a); \
     octave_value retval = octave_value (- v. TYPE ## _scalar_value ()); \
     return retval; \
   } \
@@ -183,7 +191,8 @@
  \
   DEFBINOP (PFX ## _div, T1 ## scalar, T2 ## scalar) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## T1 ## scalar&, const octave_ ## T2 ## scalar&); \
+    const octave_ ## T1 ## scalar& v1 = dynamic_cast<const octave_ ## T1 ## scalar&> (a1); \
+    const octave_ ## T2 ## scalar& v2 = dynamic_cast<const octave_ ## T2 ## scalar&> (a2); \
  \
     if (! v2.T2 ## scalar_value ()) \
       warn_divide_by_zero (); \
@@ -196,7 +205,8 @@
  \
   DEFBINOP (PFX ## _ldiv, T1 ## scalar, T2 ## scalar) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## T1 ## scalar&, const octave_ ## T2 ## scalar&); \
+    const octave_ ## T1 ## scalar& v1 = dynamic_cast<const octave_ ## T1 ## scalar&> (a1); \
+    const octave_ ## T2 ## scalar& v2 = dynamic_cast<const octave_ ## T2 ## scalar&> (a2); \
  \
     if (! v1.T1 ## scalar_value ()) \
       warn_divide_by_zero (); \
@@ -209,7 +219,8 @@
  \
   DEFBINOP (PFX ## _el_div, T1 ## scalar, T2 ## scalar) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## T1 ## scalar&, const octave_ ## T2 ## scalar&); \
+    const octave_ ## T1 ## scalar& v1 = dynamic_cast<const octave_ ## T1 ## scalar&> (a1); \
+    const octave_ ## T2 ## scalar& v2 = dynamic_cast<const octave_ ## T2 ## scalar&> (a2); \
  \
     if (! v2.T2 ## scalar_value ()) \
       warn_divide_by_zero (); \
@@ -222,7 +233,8 @@
  \
   DEFBINOP (PFX ## _el_ldiv, T1 ## scalar, T2 ## scalar) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## T1 ## scalar&, const octave_ ## T2 ## scalar&); \
+    const octave_ ## T1 ## scalar& v1 = dynamic_cast<const octave_ ## T1 ## scalar&> (a1); \
+    const octave_ ## T2 ## scalar& v2 = dynamic_cast<const octave_ ## T2 ## scalar&> (a2); \
  \
     if (! v1.T1 ## scalar_value ()) \
       warn_divide_by_zero (); \
@@ -234,14 +246,16 @@
 #define OCTAVE_SS_INT_BOOL_OPS(PFX, T1, T2, Z1, Z2) \
   DEFBINOP (PFX ## _el_and, T2, T2) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## T1 ## scalar&, const octave_ ## T2 ## scalar&); \
+    const octave_ ## T1 ## scalar& v1 = dynamic_cast<const octave_ ## T1 ## scalar&> (a1); \
+    const octave_ ## T2 ## scalar& v2 = dynamic_cast<const octave_ ## T2 ## scalar&> (a2); \
  \
     return v1.T1 ## scalar_value () != Z1 && v2.T2 ## scalar_value () != Z2; \
   } \
  \
   DEFBINOP (PFX ## _el_or, T1, T2) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## T1 ## scalar&, const octave_ ## T2 ## scalar&); \
+    const octave_ ## T1 ## scalar& v1 = dynamic_cast<const octave_ ## T1 ## scalar&> (a1); \
+    const octave_ ## T2 ## scalar& v2 = dynamic_cast<const octave_ ## T2 ## scalar&> (a2); \
  \
     return v1.T1 ## scalar_value () != Z1 || v2.T2 ## scalar_value () != Z2; \
   }
@@ -313,7 +327,8 @@
  \
   /* DEFBINOP (PFX ## _div, TS ## scalar, TM ## matrix) */ \
   /* { */ \
-  /* CAST_BINOP_ARGS (const octave_ ## TS ## scalar&, const octave_ ## TM ## matrix&); */ \
+  /* const octave_ ## TS ## scalar& v1 = dynamic_cast<const octave_ ## TS ## scalar&> (a1); */ \
+  /* const octave_ ## TM ## matrix& v2 = dynamic_cast<const octave_ ## TM ## matrix&> (a2); */ \
   /* */ \
   /* Matrix m1 = v1.TM ## matrix_value (); */ \
   /* Matrix m2 = v2.TM ## matrix_value (); */ \
@@ -325,7 +340,8 @@
  \
   DEFBINOP (PFX ## _ldiv, TS ## scalar, TM ## matrix) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## TS ## scalar&, const octave_ ## TM ## matrix&); \
+    const octave_ ## TS ## scalar& v1 = dynamic_cast<const octave_ ## TS ## scalar&> (a1); \
+    const octave_ ## TM ## matrix& v2 = dynamic_cast<const octave_ ## TM ## matrix&> (a2); \
  \
     if (! v1.TS ## scalar_value ()) \
       warn_divide_by_zero (); \
@@ -337,7 +353,8 @@
   DEFINTNDBINOP_OP (PFX ## _el_mul, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, *, TI) \
   DEFBINOP (PFX ## _el_div, TS ## scalar, TM ## matrix) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## TS ## scalar&, const octave_ ## TM ## matrix&); \
+    const octave_ ## TS ## scalar& v1 = dynamic_cast<const octave_ ## TS ## scalar&> (a1); \
+    const octave_ ## TM ## matrix& v2 = dynamic_cast<const octave_ ## TM ## matrix&> (a2); \
  \
     octave_value retval = octave_value (v1.TS ## scalar_value () / v2.TM ## array_value ()); \
     return retval; \
@@ -347,7 +364,8 @@
  \
   DEFBINOP (PFX ## _el_ldiv, TS ## scalar, TM ## matrix) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## TS ## scalar&, const octave_ ## TM ## matrix&); \
+    const octave_ ## TS ## scalar& v1 = dynamic_cast<const octave_ ## TS ## scalar&> (a1); \
+    const octave_ ## TM ## matrix& v2 = dynamic_cast<const octave_ ## TM ## matrix&> (a2); \
  \
     if (! v1.TS ## scalar_value ()) \
       warn_divide_by_zero (); \
@@ -435,7 +453,7 @@
 #define OCTAVE_SM_CONV(TS, TM) \
   DEFCONV (TS ## s_ ## TM ## m_conv, TM ## scalar, TM ## matrix) \
   { \
-    CAST_CONV_ARG (const octave_ ## TS ## scalar&); \
+    const octave_ ## TS ## scalar& v = dynamic_cast<const octave_ ## TS ## scalar&> (a); \
  \
     return new octave_ ## TM ## matrix (v.TM ## array_value ()); \
   }
@@ -470,7 +488,8 @@
  \
   DEFBINOP (PFX ## _div, TM ## matrix, TS ## scalar) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## TM ## matrix&, const octave_ ## TS ## scalar&); \
+    const octave_ ## TM ## matrix& v1 = dynamic_cast<const octave_ ## TM ## matrix&> (a1); \
+    const octave_ ## TS ## scalar& v2 = dynamic_cast<const octave_ ## TS ## scalar&> (a2); \
  \
     if (! v2.TS ## scalar_value ()) \
       warn_divide_by_zero (); \
@@ -483,7 +502,8 @@
  \
   /* DEFBINOP (PFX ## _ldiv, TM ## matrix, TS ## scalar) */ \
   /* { */ \
-  /* CAST_BINOP_ARGS (const octave_ ## TM ## matrix&, const octave_ ## TS ## scalar&); */ \
+  /* const octave_ ## TM ## matrix& v1 = dynamic_cast<const octave_ ## TM ## matrix&> (a1); */ \
+  /* const octave_ ## TS ## scalar& v2 = dynamic_cast<const octave_ ## TS ## scalar&> (a2); */ \
   /* */ \
   /* Matrix m1 = v1.TM ## matrix_value (); */ \
   /* Matrix m2 = v2.TM ## matrix_value (); */ \
@@ -495,7 +515,8 @@
  \
   DEFBINOP (PFX ## _el_div, TM ## matrix, TS ## scalar) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## TM ## matrix&, const octave_ ## TS ## scalar&); \
+    const octave_ ## TM ## matrix& v1 = dynamic_cast<const octave_ ## TM ## matrix&> (a1); \
+    const octave_ ## TS ## scalar& v2 = dynamic_cast<const octave_ ## TS ## scalar&> (a2); \
  \
     if (! v2.TS ## scalar_value ()) \
       warn_divide_by_zero (); \
@@ -508,7 +529,8 @@
  \
   DEFBINOP (PFX ## _el_ldiv, TM ## matrix, TS ## scalar) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## TM ## matrix&, const octave_ ## TS ## scalar&); \
+    const octave_ ## TM ## matrix& v1 = dynamic_cast<const octave_ ## TM ## matrix&> (a1); \
+    const octave_ ## TS ## scalar& v2 = dynamic_cast<const octave_ ## TS ## scalar&> (a2); \
     \
     octave_value retval = v2.TS ## scalar_value () / v1.TM ## array_value (); \
     return retval; \
@@ -623,14 +645,14 @@
   DEFNDUNOP_OP (m_uplus, TYPE ## _matrix, TYPE ## _array, /* no-op */) \
   DEFUNOP (m_uminus, TYPE ## _matrix) \
   { \
-    CAST_UNOP_ARG (const octave_ ## TYPE ## _matrix &); \
+    const octave_ ## TYPE ## _matrix & v = dynamic_cast<const octave_ ## TYPE ## _matrix &> (a); \
     octave_value retval = octave_value (- v. TYPE ## _array_value ()); \
     return retval; \
   } \
  \
   DEFUNOP (m_transpose, TYPE ## _matrix) \
   { \
-    CAST_UNOP_ARG (const octave_ ## TYPE ## _matrix&); \
+    const octave_ ## TYPE ## _matrix& v = dynamic_cast<const octave_ ## TYPE ## _matrix&> (a); \
  \
     if (v.ndims () > 2) \
       error ("transpose not defined for N-D objects"); \
@@ -666,7 +688,8 @@
  \
   DEFBINOP (PFX ## _el_ldiv, T1 ## matrix, T2 ## matrix) \
   { \
-    CAST_BINOP_ARGS (const octave_ ## T1 ## matrix&, const octave_ ## T2 ## matrix&); \
+    const octave_ ## T1 ## matrix& v1 = dynamic_cast<const octave_ ## T1 ## matrix&> (a1); \
+    const octave_ ## T2 ## matrix& v2 = dynamic_cast<const octave_ ## T2 ## matrix&> (a2); \
     \
     octave_value retval = octave_value (quotient (v2.T2 ## array_value (), v1.T1 ## array_value ())); \
     return retval; \
@@ -807,7 +830,7 @@
 #define OCTAVE_MM_CONV(T1, T2) \
   DEFCONV (T1 ## m_ ## T2 ## m_conv, T1 ## matrix, T2 ## matrix) \
   { \
-    CAST_CONV_ARG (const octave_ ## T1 ## matrix&); \
+    const octave_ ## T1 ## matrix& v = dynamic_cast<const octave_ ## T1 ## matrix&> (a); \
  \
     return new octave_ ## T2 ## matrix (v.T2 ## array_value ()); \
   }
--- a/libinterp/operators/op-m-cm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-m-cm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -50,7 +50,8 @@
 
 DEFBINOP (trans_mul, matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   Matrix m1 = v1.matrix_value ();
   ComplexMatrix m2 = v2.complex_matrix_value ();
@@ -61,7 +62,8 @@
 
 DEFBINOP (div, matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   ComplexMatrix ret = xdiv (v1.matrix_value (),
@@ -78,7 +80,8 @@
 
 DEFBINOP (ldiv, matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.matrix_value (),
@@ -90,7 +93,8 @@
 
 DEFBINOP (trans_ldiv, matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.matrix_value (),
@@ -113,7 +117,8 @@
 
 DEFBINOP (el_ldiv, matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   return quotient (v2.complex_array_value (), v1.array_value ());
 }
@@ -125,7 +130,7 @@
 
 DEFCONV (complex_matrix_conv, matrix, complex_matrix)
 {
-  CAST_CONV_ARG (const octave_matrix&);
+  const octave_matrix& v = dynamic_cast<const octave_matrix&> (a);
 
   return new octave_complex_matrix (ComplexNDArray (v.array_value ()));
 }
--- a/libinterp/operators/op-m-cs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-m-cs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -50,7 +50,8 @@
 
 DEFBINOP (div, matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v2.complex_value ();
 
@@ -64,7 +65,8 @@
 
 DEFBINOP (ldiv, matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Matrix m1 = v1.matrix_value ();
   ComplexMatrix m2 = v2.complex_matrix_value ();
@@ -87,7 +89,8 @@
 
 DEFBINOP (el_div, matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v2.complex_value ();
 
@@ -101,7 +104,8 @@
 
 DEFBINOP (el_ldiv, matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_complex&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   return x_el_div (v2.complex_value (), v1.array_value ());
 }
--- a/libinterp/operators/op-m-m.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-m-m.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -43,7 +43,7 @@
 
 DEFUNOP (transpose, matrix)
 {
-  CAST_UNOP_ARG (const octave_matrix&);
+  const octave_matrix& v = dynamic_cast<const octave_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -64,7 +64,8 @@
 
 DEFBINOP (div, matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   Matrix ret = xdiv (v1.matrix_value (), v2.matrix_value (), typ);
@@ -80,7 +81,8 @@
 
 DEFBINOP (ldiv, matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   Matrix ret = xleftdiv (v1.matrix_value (), v2.matrix_value (), typ);
@@ -91,21 +93,24 @@
 
 DEFBINOP (trans_mul, matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
   return octave_value(xgemm (v1.matrix_value (), v2.matrix_value (),
                              blas_trans, blas_no_trans));
 }
 
 DEFBINOP (mul_trans, matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
   return octave_value(xgemm (v1.matrix_value (), v2.matrix_value (),
                              blas_no_trans, blas_trans));
 }
 
 DEFBINOP (trans_ldiv, matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   Matrix ret = xleftdiv (v1.matrix_value (), v2.matrix_value (),
@@ -128,7 +133,8 @@
 
 DEFBINOP (el_ldiv, matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   return octave_value (quotient (v2.array_value (), v1.array_value ()));
 }
@@ -155,7 +161,7 @@
 
 CONVDECL (matrix_to_float_matrix)
 {
-  CAST_CONV_ARG (const octave_matrix&);
+  const octave_matrix& v = dynamic_cast<const octave_matrix&> (a);
 
   return new octave_float_matrix (FloatNDArray (v.array_value ()));
 }
--- a/libinterp/operators/op-m-s.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-m-s.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -44,7 +44,8 @@
 
 DEFBINOP (div, matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_scalar&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
 
@@ -58,7 +59,8 @@
 
 DEFBINOP (ldiv, matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_scalar&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   Matrix m1 = v1.matrix_value ();
   Matrix m2 = v2.matrix_value ();
@@ -81,7 +83,8 @@
 
 DEFBINOP (el_div, matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_scalar&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
 
@@ -95,7 +98,8 @@
 
 DEFBINOP (el_ldiv, matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_scalar&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   return x_el_div (v2.double_value (), v1.array_value ());
 }
--- a/libinterp/operators/op-m-scm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-m-scm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -49,7 +49,8 @@
 
 DEFBINOP (div, matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_sparse_complex_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -79,8 +80,8 @@
 
 DEFBINOP (ldiv, matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.matrix_value (),
@@ -102,8 +103,8 @@
 
 DEFBINOP (el_pow, matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value
          (elem_xpow (SparseMatrix (v1.matrix_value ()),
@@ -112,8 +113,8 @@
 
 DEFBINOP (el_ldiv, matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
   return octave_value
          (quotient (v2.sparse_complex_matrix_value (), v1.matrix_value ()));
 }
@@ -123,7 +124,8 @@
 
 DEFCATOP (m_scm, matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (octave_matrix&, const octave_sparse_complex_matrix&);
+  octave_matrix& v1 = dynamic_cast<octave_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
   SparseMatrix tmp (v1.matrix_value ());
   return octave_value (tmp. concat (v2.sparse_complex_matrix_value (),
                                     ra_idx));
@@ -131,7 +133,7 @@
 
 DEFCONV (sparse_complex_matrix_conv, matrix, sparse_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_matrix&);
+  const octave_matrix& v = dynamic_cast<const octave_matrix&> (a);
   return new octave_sparse_complex_matrix
          (SparseComplexMatrix (v.complex_matrix_value ()));
 }
--- a/libinterp/operators/op-m-sm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-m-sm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -48,7 +48,8 @@
 
 DEFBINOP (div, matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_sparse_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -77,7 +78,8 @@
 
 DEFBINOP (ldiv, matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_sparse_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   Matrix ret = xleftdiv (v1.matrix_value (), v2.matrix_value (), typ);
@@ -100,7 +102,8 @@
 
 DEFBINOP (el_pow, matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_sparse_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   return octave_value (elem_xpow (SparseMatrix (v1.matrix_value ()),
                                   v2.sparse_matrix_value ()));
@@ -108,7 +111,8 @@
 
 DEFBINOP (el_ldiv, matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_sparse_matrix&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   return octave_value
          (quotient (v2.sparse_matrix_value (), v1.matrix_value ()));
@@ -119,14 +123,15 @@
 
 DEFCATOP (m_sm, matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (octave_matrix&, const octave_sparse_matrix&);
+  octave_matrix& v1 = dynamic_cast<octave_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
   SparseMatrix tmp (v1.matrix_value ());
   return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
 }
 
 DEFCONV (sparse_matrix_conv, matrix, sparse_matrix)
 {
-  CAST_CONV_ARG (const octave_matrix&);
+  const octave_matrix& v = dynamic_cast<const octave_matrix&> (a);
   return new octave_sparse_matrix (SparseMatrix (v.matrix_value ()));
 }
 
--- a/libinterp/operators/op-pm-pm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-pm-pm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -36,7 +36,7 @@
 
 DEFUNOP (transpose, perm_matrix)
 {
-  CAST_UNOP_ARG (const octave_perm_matrix&);
+  const octave_perm_matrix& v = dynamic_cast<const octave_perm_matrix&> (a);
   return octave_value (v.perm_matrix_value ().transpose ());
 }
 
@@ -44,28 +44,31 @@
 
 DEFBINOP (div, perm_matrix, perm_matrix)
 {
-  CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_perm_matrix&);
+  const octave_perm_matrix& v1 = dynamic_cast<const octave_perm_matrix&> (a1);
+  const octave_perm_matrix& v2 = dynamic_cast<const octave_perm_matrix&> (a2);
 
   return (v1.perm_matrix_value () * v2.perm_matrix_value ().inverse ());
 }
 
 DEFBINOP (ldiv, perm_matrix, perm_matrix)
 {
-  CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_perm_matrix&);
+  const octave_perm_matrix& v1 = dynamic_cast<const octave_perm_matrix&> (a1);
+  const octave_perm_matrix& v2 = dynamic_cast<const octave_perm_matrix&> (a2);
 
   return (v1.perm_matrix_value ().inverse () * v2.perm_matrix_value ());
 }
 
 DEFBINOP (pow, perm_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_scalar&);
+  const octave_perm_matrix& v1 = dynamic_cast<const octave_perm_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   return xpow (v1.perm_matrix_value (), v2.scalar_value ());
 }
 
 CONVDECL (perm_matrix_to_matrix)
 {
-  CAST_CONV_ARG (const octave_perm_matrix&);
+  const octave_perm_matrix& v = dynamic_cast<const octave_perm_matrix&> (a);
 
   return new octave_matrix (v.matrix_value ());
 }
--- a/libinterp/operators/op-pm-scm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-pm-scm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -37,8 +37,8 @@
 
 DEFBINOP (mul_pm_scm, perm_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_perm_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_perm_matrix& v1 = dynamic_cast<const octave_perm_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -54,8 +54,8 @@
 
 DEFBINOP (ldiv_pm_scm, perm_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_perm_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_perm_matrix& v1 = dynamic_cast<const octave_perm_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   return v1.perm_matrix_value ().inverse () * v2.sparse_complex_matrix_value ();
 }
@@ -64,8 +64,8 @@
 
 DEFBINOP (mul_scm_pm, sparse_complex_matrix, perm_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_perm_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_perm_matrix& v2 = dynamic_cast<const octave_perm_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -81,8 +81,8 @@
 
 DEFBINOP (div_scm_pm, sparse_complex_matrix, perm_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_perm_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_perm_matrix& v2 = dynamic_cast<const octave_perm_matrix&> (a2);
 
   return v1.sparse_complex_matrix_value () * v2.perm_matrix_value ().inverse ();
 }
--- a/libinterp/operators/op-pm-sm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-pm-sm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -37,7 +37,8 @@
 
 DEFBINOP (mul_pm_sm, perm_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_sparse_matrix&);
+  const octave_perm_matrix& v1 = dynamic_cast<const octave_perm_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -53,7 +54,8 @@
 
 DEFBINOP (ldiv_pm_sm, perm_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_sparse_matrix&);
+  const octave_perm_matrix& v1 = dynamic_cast<const octave_perm_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   return v1.perm_matrix_value ().inverse () * v2.sparse_matrix_value ();
 }
@@ -62,7 +64,8 @@
 
 DEFBINOP (mul_sm_pm, sparse_matrix, perm_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_perm_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_perm_matrix& v2 = dynamic_cast<const octave_perm_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -78,7 +81,8 @@
 
 DEFBINOP (div_sm_pm, sparse_matrix, perm_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_perm_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_perm_matrix& v2 = dynamic_cast<const octave_perm_matrix&> (a2);
 
   return v1.sparse_matrix_value () * v2.perm_matrix_value ().inverse ();
 }
--- a/libinterp/operators/op-pm-template.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-pm-template.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -52,7 +52,8 @@
 
 DEFBINOP (mul, LMATRIX, RMATRIX)
 {
-  CAST_BINOP_ARGS (const OCTAVE_LMATRIX&, const OCTAVE_RMATRIX&);
+  const OCTAVE_LMATRIX& v1 = dynamic_cast<const OCTAVE_LMATRIX&> (a1);
+  const OCTAVE_RMATRIX& v2 = dynamic_cast<const OCTAVE_RMATRIX&> (a2);
 
   return v1.LMATRIX_VALUE () * v2.RMATRIX_VALUE ();
 }
@@ -60,14 +61,16 @@
 #ifdef LEFT
 DEFBINOP (ldiv, LMATRIX, RMATRIX)
 {
-  CAST_BINOP_ARGS (const OCTAVE_LMATRIX&, const OCTAVE_RMATRIX&);
+  const OCTAVE_LMATRIX& v1 = dynamic_cast<const OCTAVE_LMATRIX&> (a1);
+  const OCTAVE_RMATRIX& v2 = dynamic_cast<const OCTAVE_RMATRIX&> (a2);
 
   return v1.perm_matrix_value ().inverse () * v2.RMATRIX_VALUE ();
 }
 #else
 DEFBINOP (div, LMATRIX, RMATRIX)
 {
-  CAST_BINOP_ARGS (const OCTAVE_LMATRIX&, const OCTAVE_RMATRIX&);
+  const OCTAVE_LMATRIX& v1 = dynamic_cast<const OCTAVE_LMATRIX&> (a1);
+  const OCTAVE_RMATRIX& v2 = dynamic_cast<const OCTAVE_RMATRIX&> (a2);
 
   return v1.LMATRIX_VALUE () * v2.perm_matrix_value ().inverse ();
 }
--- a/libinterp/operators/op-range.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-range.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -45,7 +45,7 @@
 
 DEFUNOP (not, range)
 {
-  CAST_UNOP_ARG (const octave_range&);
+  const octave_range& v = dynamic_cast<const octave_range&> (a);
 
   return octave_value (! v.matrix_value ());
 }
@@ -55,7 +55,7 @@
 
 DEFUNOP (transpose, range)
 {
-  CAST_UNOP_ARG (const octave_range&);
+  const octave_range& v = dynamic_cast<const octave_range&> (a);
 
   return octave_value (v.matrix_value ().transpose ());
 }
@@ -88,7 +88,7 @@
 
 CONVDECL (range_to_matrix)
 {
-  CAST_CONV_ARG (const octave_range&);
+  const octave_range& v = dynamic_cast<const octave_range&> (a);
 
   return new octave_matrix (v.array_value ());
 }
--- a/libinterp/operators/op-s-cm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-s-cm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -50,7 +50,8 @@
 
 DEFBINOP (div, scalar, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   Matrix m1 = v1.matrix_value ();
   ComplexMatrix m2 = v2.complex_matrix_value ();
@@ -66,7 +67,8 @@
 
 DEFBINOP (ldiv, scalar, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   double d = v1.double_value ();
 
@@ -89,7 +91,8 @@
 
 DEFBINOP (el_ldiv, scalar, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   double d = v1.double_value ();
 
@@ -106,7 +109,7 @@
 
 DEFCONV (complex_matrix_conv, scalar, complex_matrix)
 {
-  CAST_CONV_ARG (const octave_scalar&);
+  const octave_scalar& v = dynamic_cast<const octave_scalar&> (a);
 
   return new octave_complex_matrix (ComplexMatrix (v.matrix_value ()));
 }
--- a/libinterp/operators/op-s-cs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-s-cs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -45,7 +45,8 @@
 
 DEFBINOP (div, scalar, complex)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v2.complex_value ();
 
@@ -59,7 +60,8 @@
 
 DEFBINOP (ldiv, scalar, complex)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   double d = v1.double_value ();
 
@@ -80,7 +82,8 @@
 
 DEFBINOP (el_div, scalar, complex)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v2.complex_value ();
 
@@ -94,7 +97,8 @@
 
 DEFBINOP (el_ldiv, scalar, complex)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   double d = v1.double_value ();
 
@@ -106,14 +110,16 @@
 
 DEFBINOP (el_and, scalar, complex)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   return octave_value (v1.double_value () && (v2.complex_value () != 0.0));
 }
 
 DEFBINOP (el_or, scalar, complex)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_complex&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   return octave_value (v1.double_value () || (v2.complex_value () != 0.0));
 }
--- a/libinterp/operators/op-s-m.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-s-m.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -44,7 +44,8 @@
 
 DEFBINOP (div, scalar, matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   Matrix m1 = v1.matrix_value ();
   Matrix m2 = v2.matrix_value ();
@@ -60,7 +61,8 @@
 
 DEFBINOP (ldiv, scalar, matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   double d = v1.double_value ();
 
@@ -83,7 +85,8 @@
 
 DEFBINOP (el_ldiv, scalar, matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   double d = v1.double_value ();
 
@@ -100,7 +103,7 @@
 
 DEFCONV (matrix_conv, scalar, matrix)
 {
-  CAST_CONV_ARG (const octave_scalar&);
+  const octave_scalar& v = dynamic_cast<const octave_scalar&> (a);
 
   return new octave_matrix (v.matrix_value ());
 }
--- a/libinterp/operators/op-s-s.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-s-s.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -43,7 +43,7 @@
 
 DEFUNOP (not, scalar)
 {
-  CAST_UNOP_ARG (const octave_scalar&);
+  const octave_scalar& v = dynamic_cast<const octave_scalar&> (a);
   double x = v.scalar_value ();
   if (xisnan (x))
     err_nan_to_logical_conversion ();
@@ -67,7 +67,8 @@
 
 DEFBINOP (div, scalar, scalar)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_scalar&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
 
@@ -81,7 +82,8 @@
 
 DEFBINOP (ldiv, scalar, scalar)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_scalar&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v1.double_value ();
 
@@ -102,7 +104,8 @@
 
 DEFBINOP (el_div, scalar, scalar)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_scalar&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
 
@@ -116,7 +119,8 @@
 
 DEFBINOP (el_ldiv, scalar, scalar)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_scalar&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v1.double_value ();
 
--- a/libinterp/operators/op-s-scm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-s-scm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -49,7 +49,8 @@
 
 DEFBINOP (div, scalar, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_sparse_complex_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -73,15 +74,15 @@
 
 DEFBINOP (pow, scalar, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&,
-                   const octave_sparse_complex_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
   return xpow (v1.scalar_value (), v2.complex_matrix_value ());
 }
 
 DEFBINOP (ldiv, scalar, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&,
-                   const octave_sparse_complex_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   double d = v1.double_value ();
   octave_value retval;
@@ -107,8 +108,8 @@
 
 DEFBINOP (el_ldiv, scalar, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&,
-                   const octave_sparse_complex_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   double d = v1.double_value ();
   octave_value retval;
@@ -126,7 +127,8 @@
 
 DEFCATOP (s_scm, scalar, sparse_compelx_matrix)
 {
-  CAST_BINOP_ARGS (octave_scalar&, const octave_sparse_complex_matrix&);
+  octave_scalar& v1 = dynamic_cast<octave_scalar&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
   SparseMatrix tmp (1, 1, v1.scalar_value ());
   return octave_value
          (tmp.concat (v2.sparse_complex_matrix_value (), ra_idx));
@@ -134,7 +136,7 @@
 
 DEFCONV (sparse_complex_matrix_conv, scalar, sparse_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_scalar&);
+  const octave_scalar& v = dynamic_cast<const octave_scalar&> (a);
 
   return new octave_sparse_complex_matrix
          (SparseComplexMatrix (v.complex_matrix_value ()));
--- a/libinterp/operators/op-s-sm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-s-sm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -45,7 +45,8 @@
 
 DEFBINOP (div, scalar, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_sparse_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -69,13 +70,15 @@
 
 DEFBINOP (pow, scalar, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_sparse_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
   return xpow (v1.scalar_value (), v2.matrix_value ());
 }
 
 DEFBINOP (ldiv, scalar, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_sparse_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   double d = v1.double_value ();
   octave_value retval;
@@ -101,7 +104,8 @@
 
 DEFBINOP (el_ldiv, scalar, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_scalar&, const octave_sparse_matrix&);
+  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   double d = v1.double_value ();
   octave_value retval;
@@ -119,14 +123,15 @@
 
 DEFCATOP (s_sm, scalar, sparse_matrix)
 {
-  CAST_BINOP_ARGS (octave_scalar&, const octave_sparse_matrix&);
+  octave_scalar& v1 = dynamic_cast<octave_scalar&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
   SparseMatrix tmp (1, 1, v1.scalar_value ());
   return octave_value (tmp.concat (v2.sparse_matrix_value (), ra_idx));
 }
 
 DEFCONV (sparse_matrix_conv, scalar, sparse_matrix)
 {
-  CAST_CONV_ARG (const octave_scalar&);
+  const octave_scalar& v = dynamic_cast<const octave_scalar&> (a);
 
   return new octave_sparse_matrix (SparseMatrix (v.matrix_value ()));
 }
--- a/libinterp/operators/op-sbm-b.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-sbm-b.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -54,7 +54,8 @@
 
 DEFCATOP (sbm_b, sparse_bool_matrix, bool)
 {
-  CAST_BINOP_ARGS (octave_sparse_bool_matrix&, const octave_bool&);
+  octave_sparse_bool_matrix& v1 = dynamic_cast<octave_sparse_bool_matrix&> (a1);
+  const octave_bool& v2 = dynamic_cast<const octave_bool&> (a2);
 
   SparseBoolMatrix tmp (1, 1, v2.bool_value ());
   return octave_value (v1.sparse_bool_matrix_value (). concat (tmp, ra_idx));
@@ -62,7 +63,8 @@
 
 DEFCATOP (sm_b, sparse_matrix, bool)
 {
-  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_bool&);
+  octave_sparse_matrix& v1 = dynamic_cast<octave_sparse_matrix&> (a1);
+  const octave_bool& v2 = dynamic_cast<const octave_bool&> (a2);
 
   SparseMatrix tmp (1, 1, v2.scalar_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
@@ -70,7 +72,8 @@
 
 DEFCATOP (sbm_s, sparse_bool_matrix, scalar)
 {
-  CAST_BINOP_ARGS (octave_sparse_bool_matrix&, const octave_scalar&);
+  octave_sparse_bool_matrix& v1 = dynamic_cast<octave_sparse_bool_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   SparseMatrix tmp (1, 1, v2.scalar_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
@@ -78,7 +81,8 @@
 
 DEFASSIGNOP (assign, sparse_bool_matrix, bool)
 {
-  CAST_BINOP_ARGS (octave_sparse_bool_matrix&, const octave_bool&);
+  octave_sparse_bool_matrix& v1 = dynamic_cast<octave_sparse_bool_matrix&> (a1);
+  const octave_bool& v2 = dynamic_cast<const octave_bool&> (a2);
 
   SparseBoolMatrix tmp (1, 1, v2.bool_value ());
   v1.assign (idx, tmp);
--- a/libinterp/operators/op-sbm-bm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-sbm-bm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -59,7 +59,8 @@
 
 DEFCATOP (sbm_bm, sparse_bool_matrix, bool_matrix)
 {
-  CAST_BINOP_ARGS (octave_sparse_bool_matrix&, const octave_bool_matrix&);
+  octave_sparse_bool_matrix& v1 = dynamic_cast<octave_sparse_bool_matrix&> (a1);
+  const octave_bool_matrix& v2 = dynamic_cast<const octave_bool_matrix&> (a2);
 
   SparseBoolMatrix tmp (v2.bool_matrix_value ());
   return octave_value (v1.sparse_bool_matrix_value (). concat (tmp, ra_idx));
@@ -67,7 +68,8 @@
 
 DEFCATOP (sbm_m, sparse_bool_matrix, matrix)
 {
-  CAST_BINOP_ARGS (octave_sparse_bool_matrix&, const octave_matrix&);
+  octave_sparse_bool_matrix& v1 = dynamic_cast<octave_sparse_bool_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   SparseMatrix tmp (v2.matrix_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
@@ -75,7 +77,8 @@
 
 DEFCATOP (sm_bm, sparse_matrix, bool_matrix)
 {
-  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_bool_matrix&);
+  octave_sparse_matrix& v1 = dynamic_cast<octave_sparse_matrix&> (a1);
+  const octave_bool_matrix& v2 = dynamic_cast<const octave_bool_matrix&> (a2);
 
   SparseMatrix tmp (v2.matrix_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
@@ -83,7 +86,8 @@
 
 DEFASSIGNOP (assign, sparse_bool_matrix, bool_matrix)
 {
-  CAST_BINOP_ARGS (octave_sparse_bool_matrix&, const octave_bool_matrix&);
+  octave_sparse_bool_matrix& v1 = dynamic_cast<octave_sparse_bool_matrix&> (a1);
+  const octave_bool_matrix& v2 = dynamic_cast<const octave_bool_matrix&> (a2);
 
   v1.assign (idx, SparseBoolMatrix (v2.bool_matrix_value ()));
   return octave_value ();
--- a/libinterp/operators/op-sbm-sbm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-sbm-sbm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -42,19 +42,19 @@
 
 DEFUNOP (uplus, sparse_bool_matrix)
 {
-  CAST_UNOP_ARG (const octave_sparse_bool_matrix&);
+  const octave_sparse_bool_matrix& v = dynamic_cast<const octave_sparse_bool_matrix&> (a);
   return octave_value (v.sparse_matrix_value ());
 }
 
 DEFUNOP (uminus, sparse_bool_matrix)
 {
-  CAST_UNOP_ARG (const octave_sparse_bool_matrix&);
+  const octave_sparse_bool_matrix& v = dynamic_cast<const octave_sparse_bool_matrix&> (a);
   return octave_value (- v.sparse_matrix_value ());
 }
 
 DEFUNOP (transpose, sparse_bool_matrix)
 {
-  CAST_UNOP_ARG (const octave_sparse_bool_matrix&);
+  const octave_sparse_bool_matrix& v = dynamic_cast<const octave_sparse_bool_matrix&> (a);
   return octave_value (v.sparse_bool_matrix_value ().transpose ());
 }
 
@@ -77,7 +77,7 @@
 
 CONVDECL (bool_matrix_to_double_matrix)
 {
-  CAST_CONV_ARG (const octave_sparse_bool_matrix&);
+  const octave_sparse_bool_matrix& v = dynamic_cast<const octave_sparse_bool_matrix&> (a);
 
   return new octave_sparse_matrix (SparseMatrix
                                     (v.sparse_bool_matrix_value ()));
--- a/libinterp/operators/op-scm-cm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-scm-cm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -48,8 +48,8 @@
 
 DEFBINOP (div, sparse_complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_complex_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   ComplexMatrix ret = xdiv (v1.complex_matrix_value (),
@@ -66,8 +66,8 @@
 
 DEFBINOP (ldiv, sparse_complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_complex_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -105,8 +105,8 @@
 
 DEFBINOP (el_pow, sparse_complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_complex_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   return octave_value
          (elem_xpow (v1.sparse_complex_matrix_value (), SparseComplexMatrix
@@ -115,8 +115,8 @@
 
 DEFBINOP (el_ldiv, sparse_complex_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_complex_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   return octave_value (quotient (v2.complex_matrix_value (),
                                  v1.sparse_complex_matrix_value ()));
@@ -127,8 +127,8 @@
 
 DEFCATOP (scm_cm, sparse_complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (octave_sparse_complex_matrix&,
-                   const octave_complex_matrix&);
+  octave_sparse_complex_matrix& v1 = dynamic_cast<octave_sparse_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   SparseComplexMatrix tmp (v2.complex_matrix_value ());
   return octave_value
          (v1.sparse_complex_matrix_value (). concat (tmp, ra_idx));
@@ -136,8 +136,8 @@
 
 DEFASSIGNOP (assign, sparse_complex_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (octave_sparse_complex_matrix&,
-                   const octave_complex_matrix&);
+  octave_sparse_complex_matrix& v1 = dynamic_cast<octave_sparse_complex_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   SparseComplexMatrix tmp (v2.complex_matrix_value ());
   v1.assign (idx, tmp);
--- a/libinterp/operators/op-scm-cs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-scm-cs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -46,8 +46,8 @@
 
 DEFBINOP (div, sparse_complex_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_complex&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v2.complex_value ();
   octave_value retval;
@@ -62,14 +62,15 @@
 
 DEFBINOP (pow, sparse_complex_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_complex&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
   return xpow (v1.complex_matrix_value (), v2.complex_value ());
 }
 
 DEFBINOP (ldiv, sparse_complex_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_complex&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -102,8 +103,8 @@
 
 DEFBINOP (el_div, sparse_complex_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_complex&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   octave_value retval;
 
@@ -121,8 +122,8 @@
 
 DEFBINOP (el_ldiv, sparse_complex_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_complex&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   return octave_value
          (x_el_div (v2.complex_value (), v1.sparse_complex_matrix_value ()));
@@ -133,7 +134,8 @@
 
 DEFCATOP (scm_cs, sparse_complex_matrix, complex)
 {
-  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, const octave_complex&);
+  octave_sparse_complex_matrix& v1 = dynamic_cast<octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
   SparseComplexMatrix tmp (1, 1, v2.complex_value ());
   return octave_value
          (v1.sparse_complex_matrix_value (). concat (tmp, ra_idx));
@@ -141,7 +143,8 @@
 
 DEFASSIGNOP (assign, sparse_complex_matrix, complex)
 {
-  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, const octave_complex&);
+  octave_sparse_complex_matrix& v1 = dynamic_cast<octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   SparseComplexMatrix tmp (1, 1, v2.complex_value ());
   v1.assign (idx, tmp);
--- a/libinterp/operators/op-scm-m.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-scm-m.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -49,8 +49,8 @@
 
 DEFBINOP (div, sparse_complex_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   ComplexMatrix ret = xdiv (v1.complex_matrix_value (),
@@ -67,7 +67,8 @@
 
 DEFBINOP (ldiv, sparse_complex_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -102,8 +103,8 @@
 
 DEFBINOP (el_pow, sparse_complex_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   return octave_value
          (elem_xpow (v1.sparse_complex_matrix_value (), SparseMatrix
@@ -112,8 +113,8 @@
 
 DEFBINOP (el_ldiv, sparse_complex_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   return octave_value
          (quotient (v2.matrix_value (), v1.sparse_complex_matrix_value ()));
@@ -124,7 +125,8 @@
 
 DEFCATOP (scm_m, sparse_complex_matrix, matrix)
 {
-  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, const octave_matrix&);
+  octave_sparse_complex_matrix& v1 = dynamic_cast<octave_sparse_complex_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
   SparseMatrix tmp (v2.matrix_value ());
   return octave_value
          (v1.sparse_complex_matrix_value (). concat (tmp, ra_idx));
@@ -132,7 +134,8 @@
 
 DEFASSIGNOP (assign, sparse_complex_matrix, matrix)
 {
-  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, const octave_matrix&);
+  octave_sparse_complex_matrix& v1 = dynamic_cast<octave_sparse_complex_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   SparseComplexMatrix tmp (v2.complex_matrix_value ());
   v1.assign (idx, tmp);
--- a/libinterp/operators/op-scm-s.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-scm-s.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -49,8 +49,8 @@
 
 DEFBINOP (div, sparse_complex_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_scalar&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
   octave_value retval;
@@ -65,8 +65,8 @@
 
 DEFBINOP (pow, sparse_complex_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_scalar&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double tmp = v2.scalar_value ();
   if (static_cast<int> (tmp) == tmp)
@@ -77,7 +77,8 @@
 
 DEFBINOP (ldiv, sparse_complex_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_scalar&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -110,8 +111,8 @@
 
 DEFBINOP (el_div, sparse_complex_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_scalar&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
   octave_value retval;
@@ -128,7 +129,8 @@
 
 DEFBINOP (el_ldiv, sparse_complex_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const octave_scalar&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   return octave_value
          (x_el_div (v2.double_value (), v1.sparse_complex_matrix_value ()));
@@ -139,7 +141,8 @@
 
 DEFCATOP (scm_s, sparse_complex_matrix, scalar)
 {
-  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, const octave_scalar&);
+  octave_sparse_complex_matrix& v1 = dynamic_cast<octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
   SparseComplexMatrix tmp (1, 1, v2.complex_value ());
   return octave_value
          (v1.sparse_complex_matrix_value (). concat (tmp, ra_idx));
@@ -147,7 +150,8 @@
 
 DEFASSIGNOP (assign, sparse_complex_matrix, scalar)
 {
-  CAST_BINOP_ARGS (octave_sparse_complex_matrix&, const octave_scalar&);
+  octave_sparse_complex_matrix& v1 = dynamic_cast<octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   SparseComplexMatrix tmp (1, 1, v2.complex_value ());
   v1.assign (idx, tmp);
--- a/libinterp/operators/op-scm-scm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-scm-scm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -58,7 +58,7 @@
 
 DEFUNOP (transpose, sparse_complex_matrix)
 {
-  CAST_UNOP_ARG (const octave_sparse_complex_matrix&);
+  const octave_sparse_complex_matrix& v = dynamic_cast<const octave_sparse_complex_matrix&> (a);
   return octave_value
          (v.sparse_complex_matrix_value ().transpose (),
           v.matrix_type ().transpose ());
@@ -66,7 +66,7 @@
 
 DEFUNOP (hermitian, sparse_complex_matrix)
 {
-  CAST_UNOP_ARG (const octave_sparse_complex_matrix&);
+  const octave_sparse_complex_matrix& v = dynamic_cast<const octave_sparse_complex_matrix&> (a);
   return octave_value
          (v.sparse_complex_matrix_value ().hermitian (),
           v.matrix_type ().transpose ());
@@ -75,14 +75,14 @@
 #if 0
 DEFUNOP (incr, sparse_complex_matrix)
 {
-  CAST_UNOP_ARG (const octave_sparse_complex_matrix&);
+  const octave_sparse_complex_matrix& v = dynamic_cast<const octave_sparse_complex_matrix&> (a);
 
   return octave_value (v.complex_matrix_value () .increment ());
 }
 
 DEFUNOP (decr, sparse_complex_matrix)
 {
-  CAST_UNOP_ARG (const octave_sparse_complex_matrix&);
+  const octave_sparse_complex_matrix& v = dynamic_cast<const octave_sparse_complex_matrix&> (a);
 
   return octave_value (v.complex_matrix_value () .decrement ());
 }
@@ -97,8 +97,8 @@
 
 DEFBINOP (div, sparse_complex_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -127,8 +127,8 @@
 
 DEFBINOP (ldiv, sparse_complex_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -165,8 +165,8 @@
 
 DEFBINOP (el_ldiv, sparse_complex_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value (quotient (v2.sparse_complex_matrix_value (),
                                  v1.sparse_complex_matrix_value ()));
--- a/libinterp/operators/op-scm-sm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-scm-sm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -47,8 +47,8 @@
 
 DEFBINOP (div, sparse_complex_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_sparse_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -77,8 +77,8 @@
 
 DEFBINOP (ldiv, sparse_complex_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_sparse_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -114,8 +114,8 @@
 
 DEFBINOP (el_ldiv, sparse_complex_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_complex_matrix&,
-                   const octave_sparse_matrix&);
+  const octave_sparse_complex_matrix& v1 = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   return octave_value (quotient (v2.sparse_matrix_value (),
                                  v1.sparse_complex_matrix_value ()));
--- a/libinterp/operators/op-sm-cm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-sm-cm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -48,8 +48,8 @@
 
 DEFBINOP (div, sparse_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&,
-                   const octave_complex_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   ComplexMatrix ret = xdiv (v1.matrix_value (),
@@ -66,7 +66,8 @@
 
 DEFBINOP (ldiv, sparse_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -101,8 +102,8 @@
 
 DEFBINOP (el_pow, sparse_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&,
-                   const octave_complex_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   return octave_value
          (elem_xpow (v1.sparse_matrix_value (), SparseComplexMatrix
@@ -111,8 +112,8 @@
 
 DEFBINOP (el_ldiv, sparse_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&,
-                   const octave_complex_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
 
   return octave_value
          (quotient (v2.complex_matrix_value (), v1.sparse_matrix_value ()));
@@ -123,14 +124,15 @@
 
 DEFCATOP (sm_cm, sparse_matrix, complex_matrix)
 {
-  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_complex_matrix&);
+  octave_sparse_matrix& v1 = dynamic_cast<octave_sparse_matrix&> (a1);
+  const octave_complex_matrix& v2 = dynamic_cast<const octave_complex_matrix&> (a2);
   SparseComplexMatrix tmp (v2.complex_matrix_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
 }
 
 DEFCONV (sparse_complex_matrix_conv, sparse_matrix, sparse_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_sparse_matrix&);
+  const octave_sparse_matrix& v = dynamic_cast<const octave_sparse_matrix&> (a);
   return new octave_complex_matrix (v.complex_matrix_value ());
 }
 
--- a/libinterp/operators/op-sm-cs.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-sm-cs.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -48,7 +48,8 @@
 
 DEFBINOP (div, sparse_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v2.complex_value ();
   octave_value retval;
@@ -63,13 +64,15 @@
 
 DEFBINOP (pow, sparse_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
   return xpow (v1.matrix_value (), v2.complex_value ());
 }
 
 DEFBINOP (ldiv, sparse_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -102,7 +105,8 @@
 
 DEFBINOP (el_div, sparse_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   Complex d = v2.complex_value ();
   octave_value retval;
@@ -119,7 +123,8 @@
 
 DEFBINOP (el_ldiv, sparse_matrix, complex)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_complex&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
 
   return octave_value (x_el_div (v2.complex_value (),
                                  v1.sparse_matrix_value ()));
@@ -130,7 +135,8 @@
 
 DEFCATOP (sm_cs, sparse_matrix, complex)
 {
-  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_complex&);
+  octave_sparse_matrix& v1 = dynamic_cast<octave_sparse_matrix&> (a1);
+  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
   SparseComplexMatrix tmp (1, 1, v2.complex_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
 }
--- a/libinterp/operators/op-sm-m.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-sm-m.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -48,7 +48,8 @@
 
 DEFBINOP (div, sparse_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   Matrix ret = xdiv (v1.matrix_value (), v2.matrix_value (), typ);
@@ -64,7 +65,8 @@
 
 DEFBINOP (ldiv, sparse_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -101,7 +103,8 @@
 
 DEFBINOP (el_pow, sparse_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   return octave_value (elem_xpow (v1.sparse_matrix_value (),
                                   SparseMatrix (v2.matrix_value ())));
@@ -109,7 +112,8 @@
 
 DEFBINOP (el_ldiv, sparse_matrix, matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   return octave_value
          (quotient (v2.matrix_value (), v1.sparse_matrix_value ()));
@@ -120,14 +124,16 @@
 
 DEFCATOP (sm_m, sparse_matrix, matrix)
 {
-  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_matrix&);
+  octave_sparse_matrix& v1 = dynamic_cast<octave_sparse_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
   SparseMatrix tmp (v2.matrix_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
 }
 
 DEFASSIGNOP (assign, sparse_matrix, matrix)
 {
-  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_matrix&);
+  octave_sparse_matrix& v1 = dynamic_cast<octave_sparse_matrix&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   SparseMatrix tmp (v2.matrix_value ());
   v1.assign (idx, tmp);
--- a/libinterp/operators/op-sm-s.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-sm-s.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -45,7 +45,8 @@
 
 DEFBINOP (div, sparse_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_scalar&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
   octave_value retval;
@@ -60,7 +61,8 @@
 
 DEFBINOP (pow, sparse_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_scalar&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double tmp = v2.scalar_value ();
   if (static_cast<int> (tmp) == tmp)
@@ -71,7 +73,8 @@
 
 DEFBINOP (ldiv, sparse_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_scalar&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -104,7 +107,8 @@
 
 DEFBINOP (el_div, sparse_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_scalar&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   double d = v2.double_value ();
   octave_value retval;
@@ -121,7 +125,8 @@
 
 DEFBINOP (el_ldiv, sparse_matrix, scalar)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_scalar&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   return octave_value
          (x_el_div (v2.complex_value (), v1.sparse_matrix_value ()));
@@ -132,14 +137,16 @@
 
 DEFCATOP (sm_s, sparse_matrix, scalar)
 {
-  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_scalar&);
+  octave_sparse_matrix& v1 = dynamic_cast<octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
   SparseMatrix tmp (1, 1, v2.scalar_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
 }
 
 DEFASSIGNOP (assign, sparse_matrix, scalar)
 {
-  CAST_BINOP_ARGS (octave_sparse_matrix&, const octave_scalar&);
+  octave_sparse_matrix& v1 = dynamic_cast<octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   SparseMatrix tmp (1, 1, v2.scalar_value ());
   v1.assign (idx, tmp);
--- a/libinterp/operators/op-sm-scm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-sm-scm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -47,8 +47,8 @@
 
 DEFBINOP (div, sparse_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -77,8 +77,8 @@
 
 DEFBINOP (ldiv, sparse_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -115,8 +115,8 @@
 
 DEFBINOP (el_ldiv, sparse_matrix, sparse_complex_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&,
-                   const octave_sparse_complex_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_sparse_complex_matrix& v2 = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value (quotient (v2.sparse_complex_matrix_value (),
                                  v1.sparse_matrix_value ()));
@@ -129,7 +129,7 @@
 
 DEFCONV (sparse_complex_matrix_conv, sparse_matrix, sparse_complex_matrix)
 {
-  CAST_CONV_ARG (const octave_sparse_matrix&);
+  const octave_sparse_matrix& v = dynamic_cast<const octave_sparse_matrix&> (a);
   return new octave_sparse_complex_matrix (v.sparse_complex_matrix_value ());
 }
 
--- a/libinterp/operators/op-sm-sm.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-sm-sm.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -45,7 +45,7 @@
 
 DEFUNOP (transpose, sparse_matrix)
 {
-  CAST_UNOP_ARG (const octave_sparse_matrix&);
+  const octave_sparse_matrix& v = dynamic_cast<const octave_sparse_matrix&> (a);
   return octave_value (v.sparse_matrix_value ().transpose (),
                        v.matrix_type ().transpose ());
 }
@@ -72,7 +72,8 @@
 
 DEFBINOP (div, sparse_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_sparse_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -101,7 +102,8 @@
 
 DEFBINOP (ldiv, sparse_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_sparse_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -138,7 +140,8 @@
 
 DEFBINOP (el_ldiv, sparse_matrix, sparse_matrix)
 {
-  CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_sparse_matrix&);
+  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
   return octave_value
          (quotient (v2.sparse_matrix_value (), v1.sparse_matrix_value ()));
 }
--- a/libinterp/operators/op-str-m.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-str-m.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -34,7 +34,8 @@
 
 DEFASSIGNOP (assign, char_matrix_str, octave_matrix)
 {
-  CAST_BINOP_ARGS (octave_char_matrix_str&, const octave_matrix&);
+  octave_char_matrix_str& v1 = dynamic_cast<octave_char_matrix_str&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   octave_value tmp
     = v2.convert_to_str_internal (false, false,
--- a/libinterp/operators/op-str-s.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-str-s.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -34,7 +34,8 @@
 
 DEFASSIGNOP (assign, char_matrix_str, octave_scalar)
 {
-  CAST_BINOP_ARGS (octave_char_matrix_str&, const octave_scalar&);
+  octave_char_matrix_str& v1 = dynamic_cast<octave_char_matrix_str&> (a1);
+  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
 
   octave_value tmp
     = v2.convert_to_str_internal (false, false,
--- a/libinterp/operators/op-str-str.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-str-str.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -36,7 +36,7 @@
 
 DEFUNOP (transpose, char_matrix_str)
 {
-  CAST_UNOP_ARG (const octave_char_matrix_str&);
+  const octave_char_matrix_str& v = dynamic_cast<const octave_char_matrix_str&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -48,7 +48,8 @@
 // string by string ops.
 
 #define DEFCHARNDBINOP_FN(name, op, t1, t2, e1, e2, f)  \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
     dim_vector a1_dims = a1.dims (); \
     dim_vector a2_dims = a2.dims (); \
@@ -56,7 +57,8 @@
     bool a1_is_scalar = a1_dims.all_ones (); \
     bool a2_is_scalar = a2_dims.all_ones (); \
  \
-    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    const octave_ ## t1& v1 = dynamic_cast<const octave_ ## t1&> (a1); \
+    const octave_ ## t2& v2 = dynamic_cast<const octave_ ## t2&> (a2); \
  \
     if (a1_is_scalar) \
       { \
@@ -89,7 +91,8 @@
 
 DEFASSIGNOP (assign, char_matrix_str, char_matrix_str)
 {
-  CAST_BINOP_ARGS (octave_char_matrix_str&, const octave_char_matrix_str&);
+  octave_char_matrix_str& v1 = dynamic_cast<octave_char_matrix_str&> (a1);
+  const octave_char_matrix_str& v2 = dynamic_cast<const octave_char_matrix_str&> (a2);
 
   v1.assign (idx, v2.char_array_value ());
   return octave_value ();
--- a/libinterp/operators/op-struct.cc	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/op-struct.cc	Wed Apr 27 16:13:40 2016 -0400
@@ -36,7 +36,7 @@
 
 DEFUNOP (transpose, struct)
 {
-  CAST_UNOP_ARG (const octave_struct&);
+  const octave_struct& v = dynamic_cast<const octave_struct&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -46,7 +46,7 @@
 
 DEFUNOP (scalar_transpose, scalar_struct)
 {
-  CAST_UNOP_ARG (const octave_scalar_struct&);
+  const octave_scalar_struct& v = dynamic_cast<const octave_scalar_struct&> (a);
 
   return octave_value (v.scalar_map_value ());
 }
@@ -60,7 +60,8 @@
 oct_catop_struct_matrix (octave_base_value& a1, const octave_base_value& a2,
                          const Array<octave_idx_type>&)
 {
-  CAST_BINOP_ARGS (const octave_struct&, const octave_matrix&);
+  const octave_struct& v1 = dynamic_cast<const octave_struct&> (a1);
+  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
 
   NDArray tmp = v2.array_value ();
   dim_vector dv = tmp.dims ();
@@ -75,7 +76,8 @@
 oct_catop_matrix_struct (octave_base_value& a1, const octave_base_value& a2,
                          const Array<octave_idx_type>&)
 {
-  CAST_BINOP_ARGS (const octave_matrix&, const octave_struct&);
+  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_struct& v2 = dynamic_cast<const octave_struct&> (a2);
 
   NDArray tmp = v1.array_value ();
   dim_vector dv = tmp.dims ();
--- a/libinterp/operators/ops.h	Wed Apr 27 09:31:39 2016 -0400
+++ b/libinterp/operators/ops.h	Wed Apr 27 16:13:40 2016 -0400
@@ -75,59 +75,45 @@
   octave_value_typeinfo::register_widening_op \
     (t1::static_type_id (), t2::static_type_id (), CONCAT2(oct_conv_, f));
 
-#define CAST_UNOP_ARG(t) \
-  t v = dynamic_cast<t> (a)
-
-#define CAST_BINOP_ARGS(t1, t2) \
-  t1 v1 = dynamic_cast<t1> (a1);                \
-  t2 v2 = dynamic_cast<t2> (a2)
-
-#define CAST_CONV_ARG(t) \
-  t v = dynamic_cast<t> (a)
-
-#define ASSIGNOPDECL(name) \
+#define DEFASSIGNOP(name, t1, t2) \
   static octave_value \
   CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
-                         const octave_value_list& idx, \
-                         const octave_base_value& a2)
+                                const octave_value_list& idx, \
+                                const octave_base_value& a2)
 
-#define NULLASSIGNOPDECL(name) \
-  static octave_value \
-  CONCAT2(oct_assignop_, name) (octave_base_value& a, \
-                         const octave_value_list& idx, \
-                         const octave_base_value&)
-
-#define ASSIGNANYOPDECL(name) \
+#define DEFASSIGNOP_FN(name, t1, t2, f) \
   static octave_value \
   CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
-                         const octave_value_list& idx, \
-                         const octave_value& a2)
-
-#define DEFASSIGNOP(name, t1, t2) \
-  ASSIGNOPDECL (name)
-
-#define DEFASSIGNOP_FN(name, t1, t2, f) \
-  ASSIGNOPDECL (name) \
+                                const octave_value_list& idx, \
+                                const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    CONCAT2(octave_, t1)& v1 = dynamic_cast<CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
  \
     v1.f (idx, v2.CONCAT2(t1, _value) ()); \
     return octave_value (); \
   }
 
 #define DEFNULLASSIGNOP_FN(name, t, f) \
-  NULLASSIGNOPDECL (name) \
+  static octave_value \
+  CONCAT2(oct_assignop_, name) (octave_base_value& a, \
+                                const octave_value_list& idx, \
+                                const octave_base_value&) \
   { \
-    CAST_UNOP_ARG (CONCAT2(octave_, t)&); \
+    CONCAT2(octave_, t)& v = dynamic_cast<CONCAT2(octave_, t)&> (a); \
  \
     v.f (idx); \
     return octave_value (); \
   }
 
 #define DEFNDASSIGNOP_FN(name, t1, t2, e, f) \
-  ASSIGNOPDECL (name) \
+  static octave_value \
+  CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
+                                const octave_value_list& idx, \
+                                const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    CONCAT2(octave_, t1)& v1 = dynamic_cast<CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
  \
     v1.f (idx, v2.CONCAT2(e, _value) ()); \
     return octave_value (); \
@@ -135,9 +121,13 @@
 
 // FIXME: the following currently don't handle index.
 #define DEFNDASSIGNOP_OP(name, t1, t2, f, op) \
-  ASSIGNOPDECL (name) \
+  static octave_value \
+  CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
+                                const octave_value_list& idx, \
+                                const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    CONCAT2(octave_, t1)& v1 = dynamic_cast<CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
  \
     assert (idx.empty ()); \
     v1.matrix_ref () op v2.CONCAT2(f, _value) (); \
@@ -146,9 +136,13 @@
   }
 
 #define DEFNDASSIGNOP_FNOP(name, t1, t2, f, fnop) \
-  ASSIGNOPDECL (name) \
+  static octave_value \
+  CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
+                                const octave_value_list& idx, \
+                                const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    CONCAT2(octave_, t1)& v1 = dynamic_cast<CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
  \
     assert (idx.empty ()); \
     fnop (v1.matrix_ref (), v2.CONCAT2(f, _value) ()); \
@@ -157,7 +151,10 @@
   }
 
 #define DEFASSIGNANYOP_FN(name, t1, f) \
-  ASSIGNANYOPDECL (name) \
+  static octave_value \
+  CONCAT2(oct_assignop_, name) (octave_base_value& a1, \
+                                const octave_value_list& idx, \
+                                const octave_value& a2) \
   { \
     CONCAT2(octave_, t1)& v1 = dynamic_cast<CONCAT2(octave_, t1)&> (a1); \
  \
@@ -179,7 +176,7 @@
 #define DEFCONVFNX(name, tfrom, ovtto, tto, e) \
   CONVDECL (name) \
   { \
-    CAST_CONV_ARG (const CONCAT2(octave_, tfrom)&); \
+    const CONCAT2(octave_, tfrom)& v = dynamic_cast<const CONCAT2(octave_, tfrom)&> (a); \
  \
     return new CONCAT2(octave_, ovtto) (CONCAT2(tto, NDArray) (v.CONCAT2(e, array_value) ())); \
   }
@@ -187,7 +184,7 @@
 #define DEFCONVFNX2(name, tfrom, ovtto, e) \
   CONVDECL (name) \
   { \
-    CAST_CONV_ARG (const CONCAT2(octave_, tfrom)&); \
+    const CONCAT2(octave_, tfrom)& v = dynamic_cast<const CONCAT2(octave_, tfrom)&> (a); \
  \
     return new CONCAT2(octave_, ovtto) (v.CONCAT2(e, array_value) ()); \
   }
@@ -195,7 +192,7 @@
 #define DEFDBLCONVFN(name, ovtfrom, e) \
   CONVDECL (name) \
   { \
-    CAST_CONV_ARG (const CONCAT2(octave_, ovtfrom)&); \
+    const CONCAT2(octave_, ovtfrom)& v = dynamic_cast<const CONCAT2(octave_, ovtfrom)&> (a); \
  \
     return new octave_matrix (NDArray (v.CONCAT2(e, _value) ())); \
   }
@@ -203,7 +200,7 @@
 #define DEFFLTCONVFN(name, ovtfrom, e) \
   CONVDECL (name) \
   { \
-    CAST_CONV_ARG (const CONCAT2(octave_, ovtfrom)&); \
+    const CONCAT2(octave_, ovtfrom)& v = dynamic_cast<const CONCAT2(octave_, ovtfrom)&> (a); \
  \
     return new octave_float_matrix (FloatNDArray (v.CONCAT2(e, _value) ())); \
   }
@@ -223,43 +220,45 @@
 #define DEFCONVFN2(name, tfrom, sm, tto) \
   DEFCONVFNX2 (name, CONCAT3(tfrom, _, sm), CONCAT2(tto, _matrix), CONCAT2(tto, _))
 
-#define UNOPDECL(name, a) \
+#define DEFUNOPX(name, t) \
+  static octave_value \
+  CONCAT2(oct_unop_, name) (const octave_base_value&)
+
+#define DEFUNOP(name, t) \
   static octave_value \
   CONCAT2(oct_unop_, name) (const octave_base_value& a)
 
-#define DEFUNOPX(name, t) \
-  UNOPDECL (name, , )
-
-#define DEFUNOP(name, t) \
-  UNOPDECL (name, a)
-
 #define DEFUNOP_OP(name, t, op) \
-  UNOPDECL (name, a) \
+  static octave_value \
+  CONCAT2(oct_unop_, name) (const octave_base_value& a) \
   { \
-    CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
+    const CONCAT2(octave_, t)& v = dynamic_cast<const CONCAT2(octave_, t)&> (a); \
     return octave_value (op v.CONCAT2(t, _value) ()); \
   }
 
 #define DEFNDUNOP_OP(name, t, e, op) \
-  UNOPDECL (name, a) \
+  static octave_value \
+  CONCAT2(oct_unop_, name) (const octave_base_value& a) \
   { \
-    CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
+    const CONCAT2(octave_, t)& v = dynamic_cast<const CONCAT2(octave_, t)&> (a); \
     return octave_value (op v.CONCAT2(e, _value) ()); \
   }
 
 // FIXME: in some cases, the constructor isn't necessary.
 
 #define DEFUNOP_FN(name, t, f) \
-  UNOPDECL (name, a) \
+  static octave_value \
+  CONCAT2(oct_unop_, name) (const octave_base_value& a) \
   { \
-    CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
+    const CONCAT2(octave_, t)& v = dynamic_cast<const CONCAT2(octave_, t)&> (a); \
     return octave_value (f (v.CONCAT2(t, _value) ())); \
   }
 
 #define DEFNDUNOP_FN(name, t, e, f) \
-  UNOPDECL (name, a) \
+  static octave_value \
+  CONCAT2(oct_unop_, name) (const octave_base_value& a) \
   { \
-    CAST_UNOP_ARG (const CONCAT2(octave_, t)&); \
+    const CONCAT2(octave_, t)& v = dynamic_cast<const CONCAT2(octave_, t)&> (a); \
     return octave_value (f (v.CONCAT2(e, _value) ())); \
   }
 
@@ -267,41 +266,45 @@
   static void \
   CONCAT2(oct_unop_, name) (octave_base_value& a) \
   { \
-    CAST_UNOP_ARG (CONCAT2(octave_, t)&); \
+    CONCAT2(octave_, t)& v = dynamic_cast<CONCAT2(octave_, t)&> (a); \
     v.method (); \
   }
 
-#define BINOPDECL(name, a1, a2) \
+#define DEFBINOPX(name, t1, t2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value&, const octave_base_value&)
+
+#define DEFBINOP(name, t1, t2) \
   static octave_value \
   CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2)
 
-#define DEFBINOPX(name, t1, t2) \
-  BINOPDECL (name, , )
-
-#define DEFBINOP(name, t1, t2) \
-  BINOPDECL (name, a1, a2)
-
 #define DEFBINOP_OP(name, t1, t2, op) \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    const CONCAT2(octave_, t1)& v1 = dynamic_cast<const CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
     return octave_value \
       (v1.CONCAT2(t1, _value) () op v2.CONCAT2(t2, _value) ()); \
   }
 
 #define DEFCMPLXCMPOP_OP(name, t1, t2, op) \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    const CONCAT2(octave_, t1)& v1 = dynamic_cast<const CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
     warn_complex_cmp (); \
     return octave_value \
       (v1.CONCAT2(t1, _value) () op v2.CONCAT2(t2, _value) ()); \
   }
 
 #define DEFSCALARBOOLOP_OP(name, t1, t2, op) \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    const CONCAT2(octave_, t1)& v1 = dynamic_cast<const CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
     if (xisnan (v1.CONCAT2(t1, _value) ()) || xisnan (v2.CONCAT2(t2, _value) ())) \
       err_nan_to_logical_conversion (); \
  \
@@ -310,9 +313,11 @@
   }
 
 #define DEFNDBINOP_OP(name, t1, t2, e1, e2, op) \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    const CONCAT2(octave_, t1)& v1 = dynamic_cast<const CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
     return octave_value \
       (v1.CONCAT2(e1, _value) () op v2.CONCAT2(e2, _value) ()); \
   }
@@ -320,57 +325,71 @@
 // FIXME: in some cases, the constructor isn't necessary.
 
 #define DEFBINOP_FN(name, t1, t2, f) \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    const CONCAT2(octave_, t1)& v1 = dynamic_cast<const CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
     return octave_value (f (v1.CONCAT2(t1, _value) (), v2.CONCAT2(t2, _value) ())); \
   }
 
 #define DEFNDBINOP_FN(name, t1, t2, e1, e2, f) \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    const CONCAT2(octave_, t1)& v1 = dynamic_cast<const CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
     return octave_value (f (v1.CONCAT2(e1, _value) (), v2.CONCAT2(e2, _value) ())); \
   }
 
 #define DEFNDCMPLXCMPOP_FN(name, t1, t2, e1, e2, f) \
-  BINOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1, const octave_base_value& a2) \
   { \
-    CAST_BINOP_ARGS (const CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    const CONCAT2(octave_, t1)& v1 = dynamic_cast<const CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
     return octave_value (f (v1.CONCAT2(e1, _value) (), v2.CONCAT2(e2, _value) ())); \
   }
 
-#define CATOPDECL(name, a1, a2) \
+#define DEFCATOPX(name, t1, t2) \
+  static octave_value \
+  CONCAT2(oct_catop_, name) (octave_base_value&, const octave_base_value&, \
+                             const Array<octave_idx_type>& ra_idx)
+
+#define DEFCATOP(name, t1, t2)  \
   static octave_value \
   CONCAT2(oct_catop_, name) (octave_base_value& a1, const octave_base_value& a2, \
-                      const Array<octave_idx_type>& ra_idx)
-
-#define DEFCATOPX(name, t1, t2) \
-  CATOPDECL (name, , )
-
-#define DEFCATOP(name, t1, t2)  \
-  CATOPDECL (name, a1, a2)
+                             const Array<octave_idx_type>& ra_idx)
 
 // FIXME: in some cases, the constructor isn't necessary.
 
 #define DEFCATOP_FN(name, t1, t2, f) \
-  CATOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_catop_, name) (octave_base_value& a1, const octave_base_value& a2, \
+                             const Array<octave_idx_type>& ra_idx) \
   { \
-    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    CONCAT2(octave_, t1)& v1 = dynamic_cast<CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
     return octave_value (v1.CONCAT2(t1, _value) () . f (v2.CONCAT2(t2, _value) (), ra_idx)); \
   }
 
 #define DEFNDCATOP_FN(name, t1, t2, e1, e2, f) \
-  CATOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_catop_, name) (octave_base_value& a1, const octave_base_value& a2, \
+                             const Array<octave_idx_type>& ra_idx) \
   { \
-    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    CONCAT2(octave_, t1)& v1 = dynamic_cast<CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
     return octave_value (v1.CONCAT2(e1, _value) () . f (v2.CONCAT2(e2, _value) (), ra_idx)); \
   }
 
 #define DEFNDCHARCATOP_FN(name, t1, t2, f) \
-  CATOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_catop_, name) (octave_base_value& a1, const octave_base_value& a2, \
+                             const Array<octave_idx_type>& ra_idx) \
   { \
-    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    CONCAT2(octave_, t1)& v1 = dynamic_cast<CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
  \
     return octave_value (v1.char_array_value () . f (v2.char_array_value (), ra_idx), \
                          ((a1.is_sq_string () || a2.is_sq_string ()) \
@@ -381,9 +400,12 @@
 // of the first.  Hmm.
 
 #define DEFNDCATOP_FN2(name, t1, t2, tc1, tc2, e1, e2, f) \
-  CATOPDECL (name, a1, a2) \
+  static octave_value \
+  CONCAT2(oct_catop_, name) (octave_base_value& a1, const octave_base_value& a2, \
+                             const Array<octave_idx_type>& ra_idx) \
   { \
-    CAST_BINOP_ARGS (CONCAT2(octave_, t1)&, const CONCAT2(octave_, t2)&); \
+    CONCAT2(octave_, t1)& v1 = dynamic_cast<CONCAT2(octave_, t1)&> (a1); \
+    const CONCAT2(octave_, t2)& v2 = dynamic_cast<const CONCAT2(octave_, t2)&> (a2); \
     return octave_value (tc1 (v1.CONCAT2(e1, _value) ()) . f (tc2 (v2.CONCAT2(e2, _value) ()), ra_idx)); \
   }