# HG changeset patch
# User Petter Tomner <tomner@kth.se>
# Date 1637509798 -3600
#      Sun Nov 21 16:49:58 2021 +0100
# Node ID fa58b36eaffe1d2811c9a141a8b7168c60cd0e58
# Parent  1a3cd0f2e0963e2f733a0cd315d3b38fd4bfcd7d
interpreter: Use static instead of dynamic casts

Change dynamic_cast to static_cast by default in operators, using
macro DYNORSTAT_CAST, to speed up interpreter.

New flag in configure script "--enable-internal-checks", to enable
expensive but useful checks for verification or debugging. With the
flag, OCTAVE_ENABLE_INTERNAL_CHECKS is defined.

	* configure.ac: New flag "internal-checks"

libinterp/operators/
	* op-b-b.cc: Change dynamic_cast to DYNORSTAT_CAST
	* op-b-bm.cc: ... dito
	* op-b-sbm.cc
	* op-bm-b.cc
	* op-bm-bm.cc
	* op-bm-sbm.cc
	* op-cdm-cdm.cc
	* op-cell.cc
	* op-chm.cc
	* op-class.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.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-mi.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: Define DYNORSTAT_CAST

diff -r 1a3cd0f2e096 -r fa58b36eaffe configure.ac
--- a/configure.ac	Wed Dec 22 23:22:07 2021 +0100
+++ b/configure.ac	Sun Nov 21 16:49:58 2021 +0100
@@ -947,6 +947,20 @@
     [Define to 1 to truncate intermediate FP results.])
 fi
 
+### Enable internal checks
+
+## The checks slow down the execution and are redundant,
+## but useful for debugging or verifying GNU Octave.
+ENABLE_INTERNAL_CHECKS=no
+AC_ARG_ENABLE([internal-checks],
+  [AS_HELP_STRING([--enable-internal-checks],
+    [Enable internal checks that are redundant but useful to debug or verify GNU Octave])],
+  [if test "$enableval" = yes; then ENABLE_INTERNAL_CHECKS=yes; fi], [])
+if test $ENABLE_INTERNAL_CHECKS = yes; then
+  AC_DEFINE(OCTAVE_ENABLE_INTERNAL_CHECKS, 1,
+    [Define to 1 to enable internal checks.])
+fi
+
 ### Determine extra CFLAGS, CXXFLAGS that may be necessary for Octave.
 
 ## On Intel systems with gcc, we need to compile with -mieee-fp to get full
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-b-b.cc
--- a/libinterp/operators/op-b-b.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-b-b.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -65,14 +65,14 @@
 static octave_value
 oct_unop_uplus (const octave_base_value& a)
 {
-  const octave_bool& v = dynamic_cast<const octave_bool&> (a);
+  const octave_bool& v = DYNORSTAT_CAST<const octave_bool&> (a);
   return octave_value (v.double_value ());
 }
 
 static octave_value
 oct_unop_uminus (const octave_base_value& a)
 {
-  const octave_bool& v = dynamic_cast<const octave_bool&> (a);
+  const octave_bool& v = DYNORSTAT_CAST<const octave_bool&> (a);
   return octave_value (- v.double_value ());
 }
 
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-b-bm.cc
--- a/libinterp/operators/op-b-bm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-b-bm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -61,7 +61,7 @@
 
 DEFCONV (bool_matrix_conv, bool, bool_matrix)
 {
-  const octave_bool& v = dynamic_cast<const octave_bool&> (a);
+  const octave_bool& v = DYNORSTAT_CAST<const octave_bool&> (a);
 
   return new octave_bool_matrix (v.bool_matrix_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-b-sbm.cc
--- a/libinterp/operators/op-b-sbm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-b-sbm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -51,9 +51,9 @@
 
 DEFCATOP (b_sbm, bool, sparse_bool_matrix)
 {
-  const octave_bool& v1 = dynamic_cast<const octave_bool&> (a1);
+  const octave_bool& v1 = DYNORSTAT_CAST<const octave_bool&> (a1);
   const octave_sparse_bool_matrix& v2
-    = dynamic_cast<const octave_sparse_bool_matrix&> (a2);
+    = DYNORSTAT_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));
@@ -61,24 +61,24 @@
 
 DEFCATOP (b_sm, bool, sparse_matrix)
 {
-  const octave_bool& v1 = dynamic_cast<const octave_bool&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_bool& v1 = DYNORSTAT_CAST<const octave_bool&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_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)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
   const octave_sparse_bool_matrix& v2
-    = dynamic_cast<const octave_sparse_bool_matrix&> (a2);
+    = DYNORSTAT_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)
 {
-  const octave_bool& v = dynamic_cast<const octave_bool&> (a);
+  const octave_bool& v = DYNORSTAT_CAST<const octave_bool&> (a);
 
   return new octave_sparse_bool_matrix
     (SparseBoolMatrix (1, 1, v.bool_value ()));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-bm-b.cc
--- a/libinterp/operators/op-bm-b.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-bm-b.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -74,7 +74,7 @@
                               const octave_value_list& idx,
                               const octave_base_value& a2)
 {
-  octave_bool_matrix& v1 = dynamic_cast<octave_bool_matrix&> (a1);
+  octave_bool_matrix& v1 = DYNORSTAT_CAST<octave_bool_matrix&> (a1);
 
   // FIXME: perhaps add a warning for this conversion
   //        if the values are not all 0 or 1?
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-bm-bm.cc
--- a/libinterp/operators/op-bm-bm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-bm-bm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -63,7 +63,7 @@
 
 DEFUNOP (transpose, bool_matrix)
 {
-  const octave_bool_matrix& v = dynamic_cast<const octave_bool_matrix&> (a);
+  const octave_bool_matrix& v = DYNORSTAT_CAST<const octave_bool_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -115,7 +115,7 @@
                               const octave_value_list& idx,
                               const octave_base_value& a2)
 {
-  octave_bool_matrix& v1 = dynamic_cast<octave_bool_matrix&> (a1);
+  octave_bool_matrix& v1 = DYNORSTAT_CAST<octave_bool_matrix&> (a1);
 
   // FIXME: perhaps add a warning for this conversion
   //        if the values are not all 0 or 1?
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-bm-sbm.cc
--- a/libinterp/operators/op-bm-sbm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-bm-sbm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -53,9 +53,9 @@
 
 DEFCATOP (bm_sbm, bool_matrix, sparse_bool_matrix)
 {
-  const octave_bool_matrix& v1 = dynamic_cast<const octave_bool_matrix&> (a1);
+  const octave_bool_matrix& v1 = DYNORSTAT_CAST<const octave_bool_matrix&> (a1);
   const octave_sparse_bool_matrix& v2
-    = dynamic_cast<const octave_sparse_bool_matrix&> (a2);
+    = DYNORSTAT_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));
@@ -63,24 +63,24 @@
 
 DEFCATOP (m_sbm, matrix, sparse_bool_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
   const octave_sparse_bool_matrix& v2
-    = dynamic_cast<const octave_sparse_bool_matrix&> (a2);
+    = DYNORSTAT_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)
 {
-  const octave_bool_matrix& v1 = dynamic_cast<const octave_bool_matrix&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_bool_matrix& v1 = DYNORSTAT_CAST<const octave_bool_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_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)
 {
-  const octave_bool_matrix& v = dynamic_cast<const octave_bool_matrix&> (a);
+  const octave_bool_matrix& v = DYNORSTAT_CAST<const octave_bool_matrix&> (a);
   return new octave_sparse_bool_matrix
     (SparseBoolMatrix (v.bool_matrix_value ()));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cdm-cdm.cc
--- a/libinterp/operators/op-cdm-cdm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cdm-cdm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -48,14 +48,14 @@
 DEFUNOP (transpose, complex_diag_matrix)
 {
   const octave_complex_diag_matrix& v
-    = dynamic_cast<const octave_complex_diag_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a);
   return octave_value (v.complex_diag_matrix_value ().transpose ());
 }
 
 DEFUNOP (hermitian, complex_diag_matrix)
 {
   const octave_complex_diag_matrix& v
-    = dynamic_cast<const octave_complex_diag_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a);
   return octave_value (v.complex_diag_matrix_value ().hermitian ());
 }
 
@@ -68,9 +68,9 @@
 DEFBINOP (div, complex_diag_matrix, complex_diag_matrix)
 {
   const octave_complex_diag_matrix& v1
-    = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a1);
   const octave_complex_diag_matrix& v2
-    = dynamic_cast<const octave_complex_diag_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a2);
 
   return xdiv (v1.complex_diag_matrix_value (),
                v2.complex_diag_matrix_value ());
@@ -79,9 +79,9 @@
 DEFBINOP (ldiv, complex_diag_matrix, complex_diag_matrix)
 {
   const octave_complex_diag_matrix& v1
-    = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a1);
   const octave_complex_diag_matrix& v2
-    = dynamic_cast<const octave_complex_diag_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a2);
 
   return xleftdiv (v1.complex_diag_matrix_value (),
                    v2.complex_diag_matrix_value ());
@@ -90,7 +90,7 @@
 CONVDECL (complex_diag_matrix_to_complex_matrix)
 {
   const octave_complex_diag_matrix& v
-    = dynamic_cast<const octave_complex_diag_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a);
 
   return new octave_complex_matrix (v.complex_matrix_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cell.cc
--- a/libinterp/operators/op-cell.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cell.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -43,7 +43,7 @@
 
 DEFUNOP (transpose, cell)
 {
-  const octave_cell& v = dynamic_cast<const octave_cell&> (a);
+  const octave_cell& v = DYNORSTAT_CAST<const octave_cell&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-chm.cc
--- a/libinterp/operators/op-chm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-chm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -44,7 +44,7 @@
 
 DEFUNOP (transpose, char_matrix)
 {
-  const octave_char_matrix& v = dynamic_cast<const octave_char_matrix&> (a);
+  const octave_char_matrix& v = DYNORSTAT_CAST<const octave_char_matrix&> (a);
 
   return octave_value (v.matrix_value ().transpose ());
 }
@@ -54,8 +54,8 @@
 
 DEFCATOP (chm_s, char_matrix, scalar)
 {
-  const octave_char_matrix& v1 = dynamic_cast<const octave_char_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_char_matrix& v1 = DYNORSTAT_CAST<const octave_char_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   warn_implicit_conversion ("Octave:num-to-str",
                             v2.type_name (), v1.type_name ());
@@ -66,8 +66,8 @@
 
 DEFCATOP (chm_m, char_matrix, matrix)
 {
-  const octave_char_matrix& v1 = dynamic_cast<const octave_char_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_char_matrix& v1 = DYNORSTAT_CAST<const octave_char_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   warn_implicit_conversion ("Octave:num-to-str",
                             v2.type_name (), v1.type_name ());
@@ -78,8 +78,8 @@
 
 DEFCATOP (s_chm, scalar, char_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_char_matrix& v2 = dynamic_cast<const octave_char_matrix&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_char_matrix& v2 = DYNORSTAT_CAST<const octave_char_matrix&> (a2);
 
   warn_implicit_conversion ("Octave:num-to-str",
                             v1.type_name (), v2.type_name ());
@@ -90,8 +90,8 @@
 
 DEFCATOP (m_chm, matrix, char_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_char_matrix& v2 = dynamic_cast<const octave_char_matrix&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_char_matrix& v2 = DYNORSTAT_CAST<const octave_char_matrix&> (a2);
 
   warn_implicit_conversion ("Octave:num-to-str",
                             v1.type_name (), v2.type_name ());
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-class.cc
--- a/libinterp/operators/op-class.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-class.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -92,7 +92,7 @@
       else
         {
           const octave_class& v
-            = dynamic_cast<const octave_class&> (a.get_rep ());
+            = DYNORSTAT_CAST<const octave_class&> (a.get_rep ());
 
           return octave_value (v.map_value ().transpose (),
                                v.class_name (),
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cm-cm.cc
--- a/libinterp/operators/op-cm-cm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cm-cm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -49,7 +49,7 @@
 DEFUNOP (transpose, complex_matrix)
 {
   const octave_complex_matrix& v
-    = dynamic_cast<const octave_complex_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -60,7 +60,7 @@
 DEFUNOP (hermitian, complex_matrix)
 {
   const octave_complex_matrix& v
-    = dynamic_cast<const octave_complex_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("complex-conjugate transpose not defined for N-D objects");
@@ -84,9 +84,9 @@
 DEFBINOP (div, complex_matrix, complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   ComplexMatrix ret = xdiv (v1.complex_matrix_value (),
@@ -104,9 +104,9 @@
 DEFBINOP (ldiv, complex_matrix, complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (),
@@ -119,9 +119,9 @@
 DEFBINOP (trans_mul, complex_matrix, complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   return octave_value(xgemm (v1.complex_matrix_value (),
                              v2.complex_matrix_value (),
                              blas_trans, blas_no_trans));
@@ -130,9 +130,9 @@
 DEFBINOP (mul_trans, complex_matrix, complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   return octave_value(xgemm (v1.complex_matrix_value (),
                              v2.complex_matrix_value (),
                              blas_no_trans, blas_trans));
@@ -141,9 +141,9 @@
 DEFBINOP (herm_mul, complex_matrix, complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   return octave_value(xgemm (v1.complex_matrix_value (),
                              v2.complex_matrix_value (),
                              blas_conj_trans, blas_no_trans));
@@ -152,9 +152,9 @@
 DEFBINOP (mul_herm, complex_matrix, complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   return octave_value(xgemm (v1.complex_matrix_value (),
                              v2.complex_matrix_value (),
                              blas_no_trans, blas_conj_trans));
@@ -163,9 +163,9 @@
 DEFBINOP (trans_ldiv, complex_matrix, complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (),
@@ -178,9 +178,9 @@
 DEFBINOP (herm_ldiv, complex_matrix, complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (),
@@ -214,9 +214,9 @@
 DEFBINOP (el_ldiv, complex_matrix, complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   return octave_value (quotient (v2.complex_array_value (),
                                  v1.complex_array_value ()));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cm-cs.cc
--- a/libinterp/operators/op-cm-cs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cm-cs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -48,8 +48,8 @@
 DEFBINOP (div, complex_matrix, complex)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.complex_array_value () / v2.complex_value ());
 }
@@ -59,8 +59,8 @@
 DEFBINOP (ldiv, complex_matrix, complex)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   ComplexMatrix m1 = v1.complex_matrix_value ();
   ComplexMatrix m2 = v2.complex_matrix_value ();
@@ -89,8 +89,8 @@
 DEFBINOP (el_div, complex_matrix, complex)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.complex_array_value () / v2.complex_value ());
 }
@@ -101,8 +101,8 @@
 DEFBINOP (el_ldiv, complex_matrix, complex)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return elem_xdiv (v2.complex_value (), v1.complex_array_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cm-m.cc
--- a/libinterp/operators/op-cm-m.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cm-m.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -54,8 +54,8 @@
 DEFBINOP (mul_trans, complex_matrix, matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   ComplexMatrix m1 = v1.complex_matrix_value ();
   Matrix m2 = v2.matrix_value ();
@@ -67,8 +67,8 @@
 DEFBINOP (div, complex_matrix, matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   ComplexMatrix ret = xdiv (v1.complex_matrix_value (),
@@ -86,8 +86,8 @@
 DEFBINOP (ldiv, complex_matrix, matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (),
@@ -111,8 +111,8 @@
 DEFBINOP (el_ldiv, complex_matrix, matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   return quotient (v2.array_value (), v1.complex_array_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cm-s.cc
--- a/libinterp/operators/op-cm-s.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cm-s.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -51,8 +51,8 @@
 DEFBINOP (div, complex_matrix, scalar)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v1.complex_array_value () / v2.double_value ());
 }
@@ -62,8 +62,8 @@
 DEFBINOP (ldiv, complex_matrix, scalar)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   ComplexMatrix m1 = v1.complex_matrix_value ();
   Matrix m2 = v2.matrix_value ();
@@ -87,8 +87,8 @@
 DEFBINOP (el_div, complex_matrix, scalar)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v1.complex_array_value () / v2.double_value ());
 }
@@ -98,8 +98,8 @@
 DEFBINOP (el_ldiv, complex_matrix, scalar)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return elem_xdiv (v2.double_value (), v1.complex_array_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cm-scm.cc
--- a/libinterp/operators/op-cm-scm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cm-scm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -52,9 +52,9 @@
 DEFBINOP (div, complex_matrix, sparse_complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (v1.complex_array_value () / v2.complex_value ());
@@ -78,9 +78,9 @@
 DEFBINOP (ldiv, complex_matrix, sparse_complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (),
@@ -106,9 +106,9 @@
 DEFBINOP (el_pow, complex_matrix, sparse_complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value
          (elem_xpow (SparseComplexMatrix (v1.complex_matrix_value ()),
@@ -118,9 +118,9 @@
 DEFBINOP (el_ldiv, sparse_complex_matrix, matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value (quotient (v2.sparse_complex_matrix_value (),
                                  v1.complex_matrix_value ()));
@@ -132,9 +132,9 @@
 DEFCATOP (cm_scm, complex_matrix, sparse_complex_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_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));
@@ -144,7 +144,7 @@
          sparse_complex_matrix)
 {
   const octave_complex_matrix& v
-    = dynamic_cast<const octave_complex_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a);
   return new octave_sparse_complex_matrix
          (SparseComplexMatrix (v.complex_matrix_value ()));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cm-sm.cc
--- a/libinterp/operators/op-cm-sm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cm-sm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -52,9 +52,9 @@
 DEFBINOP (div, complex_matrix, sparse_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (v1.complex_array_value () / v2.scalar_value ());
@@ -78,9 +78,9 @@
 DEFBINOP (ldiv, complex_matrix, sparse_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.complex_matrix_value (),
@@ -103,9 +103,9 @@
 DEFBINOP (el_pow, complex_matrix, sparse_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   return octave_value
          (elem_xpow (SparseComplexMatrix (v1.complex_matrix_value ()),
@@ -115,9 +115,9 @@
 DEFBINOP (el_ldiv, complex_matrix, sparse_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
   return octave_value
          (quotient (v2.sparse_matrix_value (), v1.complex_matrix_value ()));
 }
@@ -128,9 +128,9 @@
 DEFCATOP (cm_sm, complex_matrix, sparse_matrix)
 {
   const octave_complex_matrix& v1
-    = dynamic_cast<const octave_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
   SparseComplexMatrix tmp (v1.complex_matrix_value ());
   return octave_value (tmp. concat (v2.sparse_matrix_value (), ra_idx));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cs-cm.cc
--- a/libinterp/operators/op-cs-cm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cs-cm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -46,9 +46,9 @@
 
 DEFBINOP (div, complex, complex_matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   ComplexMatrix m1 = v1.complex_matrix_value ();
   ComplexMatrix m2 = v2.complex_matrix_value ();
@@ -64,9 +64,9 @@
 
 DEFBINOP (ldiv, complex, complex_matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   return octave_value (v2.complex_array_value () / v1.complex_value ());
 }
@@ -92,9 +92,9 @@
 
 DEFBINOP (el_ldiv, complex, complex_matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   return octave_value (v2.complex_array_value () / v1.complex_value ());
 }
@@ -109,7 +109,7 @@
 
 DEFCONV (complex_matrix_conv, complex, complex_matrix)
 {
-  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
+  const octave_complex& v = DYNORSTAT_CAST<const octave_complex&> (a);
 
   return new octave_complex_matrix (v.complex_matrix_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cs-cs.cc
--- a/libinterp/operators/op-cs-cs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cs-cs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -46,7 +46,7 @@
 
 DEFUNOP (not, complex)
 {
-  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
+  const octave_complex& v = DYNORSTAT_CAST<const octave_complex&> (a);
   Complex x = v.complex_value ();
   if (octave::math::isnan (x))
     octave::err_nan_to_logical_conversion ();
@@ -60,7 +60,7 @@
 
 DEFUNOP (hermitian, complex)
 {
-  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
+  const octave_complex& v = DYNORSTAT_CAST<const octave_complex&> (a);
 
   return octave_value (conj (v.complex_value ()));
 }
@@ -76,8 +76,8 @@
 
 DEFBINOP (div, complex, complex)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.complex_value () / v2.complex_value ());
 }
@@ -86,8 +86,8 @@
 
 DEFBINOP (ldiv, complex, complex)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v2.complex_value () / v1.complex_value ());
 }
@@ -103,8 +103,8 @@
 
 DEFBINOP (el_div, complex, complex)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.complex_value () / v2.complex_value ());
 }
@@ -113,24 +113,24 @@
 
 DEFBINOP (el_ldiv, complex, complex)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v2.complex_value () / v1.complex_value ());
 }
 
 DEFBINOP (el_and, complex, complex)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return v1.complex_value () != 0.0 && v2.complex_value () != 0.0;
 }
 
 DEFBINOP (el_or, complex, complex)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return v1.complex_value () != 0.0 || v2.complex_value () != 0.0;
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cs-m.cc
--- a/libinterp/operators/op-cs-m.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cs-m.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -52,8 +52,8 @@
 
 DEFBINOP (div, complex, matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   ComplexMatrix m1 = v1.complex_matrix_value ();
   Matrix m2 = v2.matrix_value ();
@@ -69,8 +69,8 @@
 
 DEFBINOP (ldiv, complex, matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   return octave_value (v2.array_value () / v1.complex_value ());
 }
@@ -88,8 +88,8 @@
 
 DEFBINOP (el_ldiv, complex, matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   return octave_value (v2.array_value () / v1.complex_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cs-s.cc
--- a/libinterp/operators/op-cs-s.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cs-s.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -47,8 +47,8 @@
 
 DEFBINOP (div, complex, scalar)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v1.complex_value () / v2.double_value ());
 }
@@ -57,8 +57,8 @@
 
 DEFBINOP (ldiv, complex, scalar)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v2.double_value () / v1.complex_value ());
 }
@@ -74,8 +74,8 @@
 
 DEFBINOP (el_div, complex, scalar)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v1.complex_value () / v2.double_value ());
 }
@@ -84,24 +84,24 @@
 
 DEFBINOP (el_ldiv, complex, scalar)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v2.double_value () / v1.complex_value ());
 }
 
 DEFBINOP (el_and, complex, scalar)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return v1.complex_value () != 0.0 && v2.double_value ();
 }
 
 DEFBINOP (el_or, complex, scalar)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return v1.complex_value () != 0.0 || v2.double_value ();
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cs-scm.cc
--- a/libinterp/operators/op-cs-scm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cs-scm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -49,9 +49,9 @@
 
 DEFBINOP (div, complex, sparse_complex_matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (SparseComplexMatrix (1, 1, v1.complex_value ()
@@ -69,17 +69,17 @@
 
 DEFBINOP (pow, complex, sparse_complex_matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
   return xpow (v1.complex_value (), v2.complex_matrix_value ());
 }
 
 DEFBINOP (ldiv, complex, sparse_complex_matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value (v2.sparse_complex_matrix_value () / v1.complex_value ());
 }
@@ -98,9 +98,9 @@
 
 DEFBINOP (el_ldiv, complex, sparse_complex_matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value (v2.sparse_complex_matrix_value () / v1.complex_value ());
 }
@@ -110,9 +110,9 @@
 
 DEFCATOP (cs_scm, complex, sparse_complex_matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_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));
@@ -120,7 +120,7 @@
 
 DEFCONV (sparse_complex_matrix_conv, complex, sparse_complex_matrix)
 {
-  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
+  const octave_complex& v = DYNORSTAT_CAST<const octave_complex&> (a);
 
   return new octave_sparse_complex_matrix
          (SparseComplexMatrix (v.complex_matrix_value ()));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-cs-sm.cc
--- a/libinterp/operators/op-cs-sm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-cs-sm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -51,8 +51,8 @@
 
 DEFBINOP (div, complex, sparse_matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (SparseComplexMatrix (1, 1, v1.complex_value () / v2.scalar_value ()));
@@ -69,15 +69,15 @@
 
 DEFBINOP (pow, complex, sparse_matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
   return xpow (v1.complex_value (), v2.matrix_value ());
 }
 
 DEFBINOP (ldiv, complex, sparse_matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   return octave_value (v2.sparse_matrix_value () / v1.complex_value ());
 }
@@ -95,8 +95,8 @@
 
 DEFBINOP (el_ldiv, complex, sparse_matrix)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   return octave_value (v2.sparse_matrix_value () / v1.complex_value ());
 }
@@ -106,16 +106,16 @@
 
 DEFCATOP (cs_sm, sparse_matrix, complex)
 {
-  const octave_complex& v1 = dynamic_cast<const octave_complex&> (a1);
+  const octave_complex& v1 = DYNORSTAT_CAST<const octave_complex&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_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)
 {
-  const octave_complex& v = dynamic_cast<const octave_complex&> (a);
+  const octave_complex& v = DYNORSTAT_CAST<const octave_complex&> (a);
 
   return new octave_sparse_matrix (SparseMatrix (v.matrix_value ()));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-dm-dm.cc
--- a/libinterp/operators/op-dm-dm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-dm-dm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -47,7 +47,7 @@
 
 DEFUNOP (transpose, diag_matrix)
 {
-  const octave_diag_matrix& v = dynamic_cast<const octave_diag_matrix&> (a);
+  const octave_diag_matrix& v = DYNORSTAT_CAST<const octave_diag_matrix&> (a);
   return octave_value (v.diag_matrix_value ().transpose ());
 }
 
@@ -59,8 +59,8 @@
 
 DEFBINOP (div, diag_matrix, 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);
+  const octave_diag_matrix& v1 = DYNORSTAT_CAST<const octave_diag_matrix&> (a1);
+  const octave_diag_matrix& v2 = DYNORSTAT_CAST<const octave_diag_matrix&> (a2);
 
   return xdiv (v1.diag_matrix_value (),
                v2.diag_matrix_value ());
@@ -68,8 +68,8 @@
 
 DEFBINOP (ldiv, diag_matrix, 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);
+  const octave_diag_matrix& v1 = DYNORSTAT_CAST<const octave_diag_matrix&> (a1);
+  const octave_diag_matrix& v2 = DYNORSTAT_CAST<const octave_diag_matrix&> (a2);
 
   return xleftdiv (v1.diag_matrix_value (),
                    v2.diag_matrix_value ());
@@ -77,7 +77,7 @@
 
 CONVDECL (diag_matrix_to_matrix)
 {
-  const octave_diag_matrix& v = dynamic_cast<const octave_diag_matrix&> (a);
+  const octave_diag_matrix& v = DYNORSTAT_CAST<const octave_diag_matrix&> (a);
 
   return new octave_matrix (v.matrix_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-dm-scm.cc
--- a/libinterp/operators/op-dm-scm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-dm-scm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -54,9 +54,9 @@
 
 DEFBINOP (mul_dm_scm, diag_matrix, sparse_complex_matrix)
 {
-  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_diag_matrix& v1 = DYNORSTAT_CAST<const octave_diag_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_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
@@ -81,9 +81,9 @@
 DEFBINOP (mul_cdm_sm, complex_diag_matrix, sparse_matrix)
 {
   const octave_complex_diag_matrix& v1
-    = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_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
@@ -108,9 +108,9 @@
 DEFBINOP (mul_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
 {
   const octave_complex_diag_matrix& v1
-    = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_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
@@ -134,9 +134,9 @@
 
 DEFBINOP (ldiv_dm_scm, diag_matrix, sparse_complex_matrix)
 {
-  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_diag_matrix& v1 = DYNORSTAT_CAST<const octave_diag_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   MatrixType typ = v2.matrix_type ();
   return xleftdiv (v1.diag_matrix_value (), v2.sparse_complex_matrix_value (),
@@ -146,9 +146,9 @@
 DEFBINOP (ldiv_cdm_sm, complex_diag_matrix, sparse_matrix)
 {
   const octave_complex_diag_matrix& v1
-    = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   MatrixType typ = v2.matrix_type ();
   return xleftdiv (v1.complex_diag_matrix_value (), v2.sparse_matrix_value (),
@@ -158,9 +158,9 @@
 DEFBINOP (ldiv_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
 {
   const octave_complex_diag_matrix& v1
-    = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   MatrixType typ = v2.matrix_type ();
   return xleftdiv (v1.complex_diag_matrix_value (),
@@ -170,9 +170,9 @@
 
 DEFBINOP (add_dm_scm, diag_matrix, sparse_complex_matrix)
 {
-  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_diag_matrix& v1 = DYNORSTAT_CAST<const octave_diag_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_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
@@ -189,9 +189,9 @@
 DEFBINOP (add_cdm_sm, complex_diag_matrix, sparse_matrix)
 {
   const octave_complex_diag_matrix& v1
-    = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_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
@@ -208,9 +208,9 @@
 DEFBINOP (add_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
 {
   const octave_complex_diag_matrix& v1
-    = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_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
@@ -226,9 +226,9 @@
 
 DEFBINOP (sub_dm_scm, diag_matrix, sparse_complex_matrix)
 {
-  const octave_diag_matrix& v1 = dynamic_cast<const octave_diag_matrix&> (a1);
+  const octave_diag_matrix& v1 = DYNORSTAT_CAST<const octave_diag_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_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
@@ -245,9 +245,9 @@
 DEFBINOP (sub_cdm_sm, complex_diag_matrix, sparse_matrix)
 {
   const octave_complex_diag_matrix& v1
-    = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_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
@@ -264,9 +264,9 @@
 DEFBINOP (sub_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
 {
   const octave_complex_diag_matrix& v1
-    = dynamic_cast<const octave_complex_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_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
@@ -285,8 +285,8 @@
 DEFBINOP (mul_scm_dm, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_diag_matrix& v2 = DYNORSTAT_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
@@ -311,9 +311,9 @@
 DEFBINOP (mul_sm_cdm, sparse_matrix, complex_diag_matrix)
 {
   const octave_sparse_matrix& v1
-    = dynamic_cast<const octave_sparse_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_complex_diag_matrix& v2
-    = dynamic_cast<const octave_complex_diag_matrix&> (a2);
+    = DYNORSTAT_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
@@ -338,9 +338,9 @@
 DEFBINOP (mul_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_complex_diag_matrix& v2
-    = dynamic_cast<const octave_complex_diag_matrix&> (a2);
+    = DYNORSTAT_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
@@ -372,8 +372,8 @@
 DEFBINOP (div_scm_dm, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_diag_matrix& v2 = DYNORSTAT_CAST<const octave_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (v1.sparse_complex_matrix_value () / v2.scalar_value ());
@@ -388,9 +388,9 @@
 DEFBINOP (div_sm_cdm, sparse_matrix, complex_diag_matrix)
 {
   const octave_sparse_matrix& v1
-    = dynamic_cast<const octave_sparse_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_complex_diag_matrix& v2
-    = dynamic_cast<const octave_complex_diag_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (v1.sparse_matrix_value () / v2.complex_value ());
@@ -405,9 +405,9 @@
 DEFBINOP (div_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_complex_diag_matrix& v2
-    = dynamic_cast<const octave_complex_diag_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (v1.sparse_complex_matrix_value () / v2.complex_value ());
@@ -422,9 +422,9 @@
 DEFBINOP (add_sm_cdm, sparse_matrix, complex_diag_matrix)
 {
   const octave_sparse_matrix& v1
-    = dynamic_cast<const octave_sparse_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_complex_diag_matrix& v2
-    = dynamic_cast<const octave_complex_diag_matrix&> (a2);
+    = DYNORSTAT_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
@@ -441,8 +441,8 @@
 DEFBINOP (add_scm_dm, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_diag_matrix& v2 = DYNORSTAT_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
@@ -459,9 +459,9 @@
 DEFBINOP (add_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_complex_diag_matrix& v2
-    = dynamic_cast<const octave_complex_diag_matrix&> (a2);
+    = DYNORSTAT_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
@@ -478,9 +478,9 @@
 DEFBINOP (sub_sm_cdm, sparse_matrix, complex_diag_matrix)
 {
   const octave_sparse_matrix& v1
-    = dynamic_cast<const octave_sparse_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_complex_diag_matrix& v2
-    = dynamic_cast<const octave_complex_diag_matrix&> (a2);
+    = DYNORSTAT_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
@@ -497,8 +497,8 @@
 DEFBINOP (sub_scm_dm, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_diag_matrix& v2 = DYNORSTAT_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
@@ -515,9 +515,9 @@
 DEFBINOP (sub_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_complex_diag_matrix& v2
-    = dynamic_cast<const octave_complex_diag_matrix&> (a2);
+    = DYNORSTAT_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
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-dm-sm.cc
--- a/libinterp/operators/op-dm-sm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-dm-sm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -43,8 +43,8 @@
 
 DEFBINOP (mul_dm_sm, diag_matrix, 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);
+  const octave_diag_matrix& v1 = DYNORSTAT_CAST<const octave_diag_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_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
@@ -67,8 +67,8 @@
 
 DEFBINOP (ldiv_dm_sm, diag_matrix, 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);
+  const octave_diag_matrix& v1 = DYNORSTAT_CAST<const octave_diag_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   MatrixType typ = v2.matrix_type ();
   return xleftdiv (v1.diag_matrix_value (), v2.sparse_matrix_value (), typ);
@@ -76,8 +76,8 @@
 
 DEFBINOP (add_dm_sm, diag_matrix, 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);
+  const octave_diag_matrix& v1 = DYNORSTAT_CAST<const octave_diag_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_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
@@ -93,8 +93,8 @@
 
 DEFBINOP (sub_dm_sm, diag_matrix, 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);
+  const octave_diag_matrix& v1 = DYNORSTAT_CAST<const octave_diag_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_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
@@ -112,8 +112,8 @@
 
 DEFBINOP (mul_sm_dm, sparse_matrix, 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);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_diag_matrix& v2 = DYNORSTAT_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
@@ -136,8 +136,8 @@
 
 DEFBINOP (div_sm_dm, sparse_matrix, 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);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_diag_matrix& v2 = DYNORSTAT_CAST<const octave_diag_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (v1.sparse_matrix_value () / v2.scalar_value ());
@@ -150,8 +150,8 @@
 
 DEFBINOP (add_sm_dm, sparse_matrix, 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);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_diag_matrix& v2 = DYNORSTAT_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
@@ -167,8 +167,8 @@
 
 DEFBINOP (sub_sm_dm, sparse_matrix, 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);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_diag_matrix& v2 = DYNORSTAT_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
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-dm-template.cc
--- a/libinterp/operators/op-dm-template.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-dm-template.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -66,8 +66,8 @@
 #if defined (DEFINEDIV)
 DEFBINOP (div, LMATRIX, RMATRIX)
 {
-  const OCTAVE_LMATRIX& v1 = dynamic_cast<const OCTAVE_LMATRIX&> (a1);
-  const OCTAVE_RMATRIX& v2 = dynamic_cast<const OCTAVE_RMATRIX&> (a2);
+  const OCTAVE_LMATRIX& v1 = DYNORSTAT_CAST<const OCTAVE_LMATRIX&> (a1);
+  const OCTAVE_RMATRIX& v2 = DYNORSTAT_CAST<const OCTAVE_RMATRIX&> (a2);
 
   return xdiv (v1.LDMATRIX_VALUE (), v2.RMATRIX_VALUE ());
 }
@@ -76,8 +76,8 @@
 #if defined (DEFINELDIV)
 DEFBINOP (ldiv, LMATRIX, RMATRIX)
 {
-  const OCTAVE_LMATRIX& v1 = dynamic_cast<const OCTAVE_LMATRIX&> (a1);
-  const OCTAVE_RMATRIX& v2 = dynamic_cast<const OCTAVE_RMATRIX&> (a2);
+  const OCTAVE_LMATRIX& v1 = DYNORSTAT_CAST<const OCTAVE_LMATRIX&> (a1);
+  const OCTAVE_RMATRIX& v2 = DYNORSTAT_CAST<const OCTAVE_RMATRIX&> (a2);
 
   return xleftdiv (v1.LMATRIX_VALUE (), v2.RDMATRIX_VALUE ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-dms-template.cc
--- a/libinterp/operators/op-dms-template.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-dms-template.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -54,24 +54,24 @@
 
 DEFBINOP (dmsdiv, MATRIX, SCALAR)
 {
-  const OCTAVE_MATRIX& v1 = dynamic_cast<const OCTAVE_MATRIX&> (a1);
-  const OCTAVE_SCALAR& v2 = dynamic_cast<const OCTAVE_SCALAR&> (a2);
+  const OCTAVE_MATRIX& v1 = DYNORSTAT_CAST<const OCTAVE_MATRIX&> (a1);
+  const OCTAVE_SCALAR& v2 = DYNORSTAT_CAST<const OCTAVE_SCALAR&> (a2);
 
   return v1.MATRIX_VALUE () / v2.SCALAR_VALUE ();
 }
 
 DEFBINOP (sdmldiv, SCALAR, MATRIX)
 {
-  const OCTAVE_SCALAR& v1 = dynamic_cast<const OCTAVE_SCALAR&> (a1);
-  const OCTAVE_MATRIX& v2 = dynamic_cast<const OCTAVE_MATRIX&> (a2);
+  const OCTAVE_SCALAR& v1 = DYNORSTAT_CAST<const OCTAVE_SCALAR&> (a1);
+  const OCTAVE_MATRIX& v2 = DYNORSTAT_CAST<const OCTAVE_MATRIX&> (a2);
 
   return v2.MATRIX_VALUE () / v1.SCALAR_VALUE ();
 }
 
 DEFBINOP (dmspow, MATRIX, SCALAR)
 {
-  const OCTAVE_MATRIX& v1 = dynamic_cast<const OCTAVE_MATRIX&> (a1);
-  const OCTAVE_SCALAR& v2 = dynamic_cast<const OCTAVE_SCALAR&> (a2);
+  const OCTAVE_MATRIX& v1 = DYNORSTAT_CAST<const OCTAVE_MATRIX&> (a1);
+  const OCTAVE_SCALAR& v2 = DYNORSTAT_CAST<const OCTAVE_SCALAR&> (a2);
 
   return xpow (v1.MATRIX_VALUE (), v2.SCALAR_VALUE ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fcdm-fcdm.cc
--- a/libinterp/operators/op-fcdm-fcdm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fcdm-fcdm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -48,14 +48,14 @@
 DEFUNOP (transpose, float_complex_diag_matrix)
 {
   const octave_float_complex_diag_matrix& v
-    = dynamic_cast<const octave_float_complex_diag_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_float_complex_diag_matrix&> (a);
   return octave_value (v.float_complex_diag_matrix_value ().transpose ());
 }
 
 DEFUNOP (hermitian, float_complex_diag_matrix)
 {
   const octave_float_complex_diag_matrix& v
-    = dynamic_cast<const octave_float_complex_diag_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_float_complex_diag_matrix&> (a);
   return octave_value (v.float_complex_diag_matrix_value ().hermitian ());
 }
 
@@ -68,9 +68,9 @@
 DEFBINOP (div, float_complex_diag_matrix, float_complex_diag_matrix)
 {
   const octave_float_complex_diag_matrix& v1
-    = dynamic_cast<const octave_float_complex_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_diag_matrix&> (a1);
   const octave_float_complex_diag_matrix& v2
-    = dynamic_cast<const octave_float_complex_diag_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_diag_matrix&> (a2);
 
   return xdiv (v1.float_complex_diag_matrix_value (),
                v2.float_complex_diag_matrix_value ());
@@ -79,9 +79,9 @@
 DEFBINOP (ldiv, float_complex_diag_matrix, float_complex_diag_matrix)
 {
   const octave_float_complex_diag_matrix& v1
-    = dynamic_cast<const octave_float_complex_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_diag_matrix&> (a1);
   const octave_float_complex_diag_matrix& v2
-    = dynamic_cast<const octave_float_complex_diag_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_diag_matrix&> (a2);
 
   return xleftdiv (v1.float_complex_diag_matrix_value (),
                    v2.float_complex_diag_matrix_value ());
@@ -90,7 +90,7 @@
 CONVDECL (float_complex_diag_matrix_to_complex_diag_matrix)
 {
   const octave_float_complex_diag_matrix& v
-    = dynamic_cast<const octave_float_complex_diag_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_float_complex_diag_matrix&> (a);
 
   return new octave_complex_diag_matrix (v.complex_diag_matrix_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fcm-fcm.cc
--- a/libinterp/operators/op-fcm-fcm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fcm-fcm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -49,7 +49,7 @@
 DEFUNOP (transpose, float_complex_matrix)
 {
   const octave_float_complex_matrix& v
-    = dynamic_cast<const octave_float_complex_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -60,7 +60,7 @@
 DEFUNOP (hermitian, float_complex_matrix)
 {
   const octave_float_complex_matrix& v
-    = dynamic_cast<const octave_float_complex_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("complex-conjugate transpose not defined for N-D objects");
@@ -84,9 +84,9 @@
 DEFBINOP (div, float_complex_matrix, float_complex_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   FloatComplexMatrix ret = xdiv (v1.float_complex_matrix_value (),
@@ -104,9 +104,9 @@
 DEFBINOP (ldiv, float_complex_matrix, float_complex_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (),
@@ -119,9 +119,9 @@
 DEFBINOP (trans_mul, float_complex_matrix, float_complex_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_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));
@@ -130,9 +130,9 @@
 DEFBINOP (mul_trans, float_complex_matrix, float_complex_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_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));
@@ -141,9 +141,9 @@
 DEFBINOP (herm_mul, float_complex_matrix, float_complex_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_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));
@@ -152,9 +152,9 @@
 DEFBINOP (mul_herm, float_complex_matrix, float_complex_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_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));
@@ -163,9 +163,9 @@
 DEFBINOP (trans_ldiv, float_complex_matrix, float_complex_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (),
@@ -179,9 +179,9 @@
 DEFBINOP (herm_ldiv, float_complex_matrix, float_complex_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (),
@@ -215,9 +215,9 @@
 DEFBINOP (el_ldiv, float_complex_matrix, float_complex_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
 
   return octave_value (quotient (v2.float_complex_array_value (),
                                  v1.float_complex_array_value ()));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fcm-fcs.cc
--- a/libinterp/operators/op-fcm-fcs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fcm-fcs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -52,9 +52,9 @@
 DEFBINOP (div, float_complex_matrix, float_complex)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex& v2
-    = dynamic_cast<const octave_float_complex&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v1.float_complex_array_value () / v2.float_complex_value ());
 }
@@ -64,9 +64,9 @@
 DEFBINOP (ldiv, float_complex_matrix, float_complex)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex& v2
-    = dynamic_cast<const octave_float_complex&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
   FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
@@ -96,9 +96,9 @@
 DEFBINOP (el_div, float_complex_matrix, float_complex)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex& v2
-    = dynamic_cast<const octave_float_complex&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v1.float_complex_array_value () / v2.float_complex_value ());
 }
@@ -109,9 +109,9 @@
 DEFBINOP (el_ldiv, float_complex_matrix, float_complex)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_complex& v2
-    = dynamic_cast<const octave_float_complex&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return elem_xdiv (v2.float_complex_value (), v1.float_complex_array_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fcm-fm.cc
--- a/libinterp/operators/op-fcm-fm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fcm-fm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -58,9 +58,9 @@
 DEFBINOP (mul_trans, float_complex_matrix, float_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_matrix& v2
-    = dynamic_cast<const octave_float_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
 
   FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
   FloatMatrix m2 = v2.float_matrix_value ();
@@ -72,9 +72,9 @@
 DEFBINOP (div, float_complex_matrix, float_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_matrix& v2
-    = dynamic_cast<const octave_float_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   FloatComplexMatrix ret = xdiv (v1.float_complex_matrix_value (),
@@ -92,9 +92,9 @@
 DEFBINOP (ldiv, float_complex_matrix, float_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_matrix& v2
-    = dynamic_cast<const octave_float_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatComplexMatrix ret = xleftdiv (v1.float_complex_matrix_value (),
@@ -127,9 +127,9 @@
 DEFBINOP (el_ldiv, float_complex_matrix, float_matrix)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_matrix& v2
-    = dynamic_cast<const octave_float_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
 
   return quotient (v2.float_array_value (), v1.float_complex_array_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fcm-fs.cc
--- a/libinterp/operators/op-fcm-fs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fcm-fs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -55,9 +55,9 @@
 DEFBINOP (div, float_complex_matrix, float)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_scalar& v2
-    = dynamic_cast<const octave_float_scalar&> (a2);
+    = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return octave_value (v1.float_complex_array_value () / v2.float_value ());
 }
@@ -67,9 +67,9 @@
 DEFBINOP (ldiv, float_complex_matrix, float)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_scalar& v2
-    = dynamic_cast<const octave_float_scalar&> (a2);
+    = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
   FloatMatrix m2 = v2.float_matrix_value ();
@@ -100,9 +100,9 @@
 DEFBINOP (el_div, float_complex_matrix, float)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_scalar& v2
-    = dynamic_cast<const octave_float_scalar&> (a2);
+    = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return octave_value (v1.float_complex_array_value () / v2.float_value ());
 }
@@ -113,9 +113,9 @@
 DEFBINOP (el_ldiv, float_complex_matrix, float)
 {
   const octave_float_complex_matrix& v1
-    = dynamic_cast<const octave_float_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a1);
   const octave_float_scalar& v2
-    = dynamic_cast<const octave_float_scalar&> (a2);
+    = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return elem_xdiv (v2.float_value (), v1.float_complex_array_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fcn.cc
--- a/libinterp/operators/op-fcn.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fcn.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -39,16 +39,16 @@
 
 DEFBINOP (eq, fcn_handle, 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);
+  const octave_fcn_handle& v1 = DYNORSTAT_CAST<const octave_fcn_handle&> (a1);
+  const octave_fcn_handle& v2 = DYNORSTAT_CAST<const octave_fcn_handle&> (a2);
 
   return is_equal_to (v1, v2);
 }
 
 DEFBINOP (ne, fcn_handle, 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);
+  const octave_fcn_handle& v1 = DYNORSTAT_CAST<const octave_fcn_handle&> (a1);
+  const octave_fcn_handle& v2 = DYNORSTAT_CAST<const octave_fcn_handle&> (a2);
 
   return ! is_equal_to (v1, v2);
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fcs-fcm.cc
--- a/libinterp/operators/op-fcs-fcm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fcs-fcm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -52,9 +52,9 @@
 DEFBINOP (div, float_complex, float_complex_matrix)
 {
   const octave_float_complex& v1
-    = dynamic_cast<const octave_float_complex&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
 
   FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
   FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
@@ -71,9 +71,9 @@
 DEFBINOP (ldiv, float_complex, float_complex_matrix)
 {
   const octave_float_complex& v1
-    = dynamic_cast<const octave_float_complex&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
 
   return octave_value (v2.float_complex_array_value () / v1.float_complex_value ());
 }
@@ -101,9 +101,9 @@
 DEFBINOP (el_ldiv, float_complex, float_complex_matrix)
 {
   const octave_float_complex& v1
-    = dynamic_cast<const octave_float_complex&> (a1);
+    = DYNORSTAT_CAST<const octave_float_complex&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
 
   return octave_value (v2.float_complex_array_value () / v1.float_complex_value ());
 }
@@ -125,7 +125,7 @@
 DEFCONV (float_complex_matrix_conv, float_complex, float_complex_matrix)
 {
   const octave_float_complex& v
-    = dynamic_cast<const octave_float_complex&> (a);
+    = DYNORSTAT_CAST<const octave_float_complex&> (a);
 
   return new octave_float_complex_matrix (v.float_complex_matrix_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fcs-fcs.cc
--- a/libinterp/operators/op-fcs-fcs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fcs-fcs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -44,7 +44,7 @@
 
 DEFUNOP (not, float_complex)
 {
-  const octave_float_complex& v = dynamic_cast<const octave_float_complex&> (a);
+  const octave_float_complex& v = DYNORSTAT_CAST<const octave_float_complex&> (a);
   FloatComplex x = v.float_complex_value ();
   if (octave::math::isnan (x))
     octave::err_nan_to_logical_conversion ();
@@ -58,7 +58,7 @@
 
 DEFUNOP (hermitian, float_complex)
 {
-  const octave_float_complex& v = dynamic_cast<const octave_float_complex&> (a);
+  const octave_float_complex& v = DYNORSTAT_CAST<const octave_float_complex&> (a);
 
   return octave_value (conj (v.float_complex_value ()));
 }
@@ -74,8 +74,8 @@
 
 DEFBINOP (div, float_complex, 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);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v1.float_complex_value () / v2.float_complex_value ());
 }
@@ -84,8 +84,8 @@
 
 DEFBINOP (ldiv, float_complex, 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);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v2.float_complex_value () / v1.float_complex_value ());
 }
@@ -101,8 +101,8 @@
 
 DEFBINOP (el_div, float_complex, 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);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v1.float_complex_value () / v2.float_complex_value ());
 }
@@ -111,16 +111,16 @@
 
 DEFBINOP (el_ldiv, float_complex, 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);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v2.float_complex_value () / v1.float_complex_value ());
 }
 
 DEFBINOP (el_and, float_complex, 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);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return (v1.float_complex_value () != 0.0f
           && v2.float_complex_value () != 0.0f);
@@ -128,8 +128,8 @@
 
 DEFBINOP (el_or, float_complex, 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);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return (v1.float_complex_value () != 0.0f
           || v2.float_complex_value () != 0.0f);
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fcs-fm.cc
--- a/libinterp/operators/op-fcs-fm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fcs-fm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -53,8 +53,8 @@
 
 DEFBINOP (div, float_complex, 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);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_matrix& v2 = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
 
   FloatComplexMatrix m1 = v1.float_complex_matrix_value ();
   FloatMatrix m2 = v2.float_matrix_value ();
@@ -70,8 +70,8 @@
 
 DEFBINOP (ldiv, float_complex, 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);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_matrix& v2 = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
 
   return octave_value (v2.float_array_value () / v1.float_complex_value ());
 }
@@ -98,8 +98,8 @@
 
 DEFBINOP (el_ldiv, float_complex, 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);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_matrix& v2 = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
 
   return octave_value (v2.float_array_value () / v1.float_complex_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fcs-fs.cc
--- a/libinterp/operators/op-fcs-fs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fcs-fs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -50,8 +50,8 @@
 
 DEFBINOP (div, float_complex, float)
 {
-  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
-  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return octave_value (v1.float_complex_value () / v2.float_value ());
 }
@@ -60,8 +60,8 @@
 
 DEFBINOP (ldiv, float_complex, float)
 {
-  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
-  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return octave_value (v2.float_value () / v1.float_complex_value ());
 }
@@ -77,8 +77,8 @@
 
 DEFBINOP (el_div, float_complex, float)
 {
-  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
-  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return octave_value (v1.float_complex_value () / v2.float_value ());
 }
@@ -87,24 +87,24 @@
 
 DEFBINOP (el_ldiv, float_complex, float)
 {
-  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
-  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return octave_value (v2.float_value () / v1.float_complex_value ());
 }
 
 DEFBINOP (el_and, float_complex, float)
 {
-  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
-  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return (v1.float_complex_value () != 0.0f && v2.float_value ());
 }
 
 DEFBINOP (el_or, float_complex, float)
 {
-  const octave_float_complex& v1 = dynamic_cast<const octave_float_complex&> (a1);
-  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
+  const octave_float_complex& v1 = DYNORSTAT_CAST<const octave_float_complex&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return (v1.float_complex_value () != 0.0f || v2.float_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fdm-fdm.cc
--- a/libinterp/operators/op-fdm-fdm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fdm-fdm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -48,7 +48,7 @@
 DEFUNOP (transpose, float_diag_matrix)
 {
   const octave_float_diag_matrix& v
-    = dynamic_cast<const octave_float_diag_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_float_diag_matrix&> (a);
   return octave_value (v.float_diag_matrix_value ().transpose ());
 }
 
@@ -61,9 +61,9 @@
 DEFBINOP (div, float_diag_matrix, float_diag_matrix)
 {
   const octave_float_diag_matrix& v1
-    = dynamic_cast<const octave_float_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_diag_matrix&> (a1);
   const octave_float_diag_matrix& v2
-    = dynamic_cast<const octave_float_diag_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_diag_matrix&> (a2);
 
   return xdiv (v1.float_diag_matrix_value (),
                v2.float_diag_matrix_value ());
@@ -72,9 +72,9 @@
 DEFBINOP (ldiv, float_diag_matrix, float_diag_matrix)
 {
   const octave_float_diag_matrix& v1
-    = dynamic_cast<const octave_float_diag_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_diag_matrix&> (a1);
   const octave_float_diag_matrix& v2
-    = dynamic_cast<const octave_float_diag_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_diag_matrix&> (a2);
 
   return xleftdiv (v1.float_diag_matrix_value (),
                    v2.float_diag_matrix_value ());
@@ -83,7 +83,7 @@
 CONVDECL (float_diag_matrix_to_float_matrix)
 {
   const octave_float_diag_matrix& v
-    = dynamic_cast<const octave_float_diag_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_float_diag_matrix&> (a);
 
   return new octave_float_matrix (v.float_matrix_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fm-fcm.cc
--- a/libinterp/operators/op-fm-fcm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fm-fcm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -58,9 +58,9 @@
 DEFBINOP (trans_mul, float_matrix, float_complex_matrix)
 {
   const octave_float_matrix& v1
-    = dynamic_cast<const octave_float_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
 
   FloatMatrix m1 = v1.float_matrix_value ();
   FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
@@ -72,9 +72,9 @@
 DEFBINOP (div, float_matrix, float_complex_matrix)
 {
   const octave_float_matrix& v1
-    = dynamic_cast<const octave_float_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   FloatComplexMatrix ret = xdiv (v1.float_matrix_value (),
@@ -92,9 +92,9 @@
 DEFBINOP (ldiv, float_matrix, float_complex_matrix)
 {
   const octave_float_matrix& v1
-    = dynamic_cast<const octave_float_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatComplexMatrix ret = xleftdiv (v1.float_matrix_value (),
@@ -107,9 +107,9 @@
 DEFBINOP (trans_ldiv, float_matrix, float_complex_matrix)
 {
   const octave_float_matrix& v1
-    = dynamic_cast<const octave_float_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatComplexMatrix ret = xleftdiv (v1.float_matrix_value (),
@@ -143,9 +143,9 @@
 DEFBINOP (el_ldiv, float_matrix, float_complex_matrix)
 {
   const octave_float_matrix& v1
-    = dynamic_cast<const octave_float_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
 
   return quotient (v2.float_complex_array_value (), v1.float_array_value ());
 }
@@ -166,7 +166,7 @@
 
 DEFCONV (float_complex_matrix_conv, float_matrix, float_complex_matrix)
 {
-  const octave_float_matrix& v = dynamic_cast<const octave_float_matrix&> (a);
+  const octave_float_matrix& v = DYNORSTAT_CAST<const octave_float_matrix&> (a);
 
   return new octave_float_complex_matrix (FloatComplexNDArray
                                            (v.float_array_value ()));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fm-fcs.cc
--- a/libinterp/operators/op-fm-fcs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fm-fcs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -55,8 +55,8 @@
 
 DEFBINOP (div, float_matrix, 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);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v1.float_array_value () / v2.float_complex_value ());
 }
@@ -65,8 +65,8 @@
 
 DEFBINOP (ldiv, float_matrix, 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);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   FloatMatrix m1 = v1.float_matrix_value ();
   FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
@@ -96,8 +96,8 @@
 
 DEFBINOP (el_div, float_matrix, 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);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v1.float_array_value () / v2.float_complex_value ());
 }
@@ -107,8 +107,8 @@
 
 DEFBINOP (el_ldiv, float_matrix, flaot_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);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return elem_xdiv (v2.float_complex_value (), v1.float_array_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fm-fm.cc
--- a/libinterp/operators/op-fm-fm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fm-fm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -48,7 +48,7 @@
 
 DEFUNOP (transpose, float_matrix)
 {
-  const octave_float_matrix& v = dynamic_cast<const octave_float_matrix&> (a);
+  const octave_float_matrix& v = DYNORSTAT_CAST<const octave_float_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -69,8 +69,8 @@
 
 DEFBINOP (div, float_matrix, 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);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_matrix& v2 = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   FloatMatrix ret = xdiv (v1.float_matrix_value (),
@@ -87,8 +87,8 @@
 
 DEFBINOP (ldiv, float_matrix, 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);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_matrix& v2 = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatMatrix ret = xleftdiv (v1.float_matrix_value (),
@@ -100,8 +100,8 @@
 
 DEFBINOP (trans_mul, float_matrix, 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);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_matrix& v2 = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
   return octave_value(xgemm (v1.float_matrix_value (),
                              v2.float_matrix_value (),
                              blas_trans, blas_no_trans));
@@ -109,8 +109,8 @@
 
 DEFBINOP (mul_trans, float_matrix, 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);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_matrix& v2 = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
   return octave_value(xgemm (v1.float_matrix_value (),
                              v2.float_matrix_value (),
                              blas_no_trans, blas_trans));
@@ -118,8 +118,8 @@
 
 DEFBINOP (trans_ldiv, float_matrix, 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);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_matrix& v2 = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   FloatMatrix ret = xleftdiv (v1.float_matrix_value (),
@@ -151,8 +151,8 @@
 
 DEFBINOP (el_ldiv, float_matrix, 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);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_matrix& v2 = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
 
   return octave_value (quotient (v2.float_array_value (),
                                  v1.float_array_value ()));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fm-fs.cc
--- a/libinterp/operators/op-fm-fs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fm-fs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -47,8 +47,8 @@
 
 DEFBINOP (div, float_matrix, float)
 {
-  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
-  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return octave_value (v1.float_array_value () / v2.float_value ());
 }
@@ -57,8 +57,8 @@
 
 DEFBINOP (ldiv, float_matrix, float)
 {
-  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
-  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   FloatMatrix m1 = v1.float_matrix_value ();
   FloatMatrix m2 = v2.float_matrix_value ();
@@ -87,8 +87,8 @@
 
 DEFBINOP (el_div, float_matrix, float)
 {
-  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
-  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return octave_value (v1.float_array_value () / v2.float_value ());
 }
@@ -98,8 +98,8 @@
 
 DEFBINOP (el_ldiv, float_matrix, float)
 {
-  const octave_float_matrix& v1 = dynamic_cast<const octave_float_matrix&> (a1);
-  const octave_float_scalar& v2 = dynamic_cast<const octave_float_scalar&> (a2);
+  const octave_float_matrix& v1 = DYNORSTAT_CAST<const octave_float_matrix&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return elem_xdiv (v2.float_value (), v1.float_array_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fs-fcm.cc
--- a/libinterp/operators/op-fs-fcm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fs-fcm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -58,9 +58,9 @@
 DEFBINOP (div, float_scalar, float_complex_matrix)
 {
   const octave_float_scalar& v1
-    = dynamic_cast<const octave_float_scalar&> (a1);
+    = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
 
   FloatMatrix m1 = v1.float_matrix_value ();
   FloatComplexMatrix m2 = v2.float_complex_matrix_value ();
@@ -77,9 +77,9 @@
 DEFBINOP (ldiv, float_scalar, float_complex_matrix)
 {
   const octave_float_scalar& v1
-    = dynamic_cast<const octave_float_scalar&> (a1);
+    = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
 
   return octave_value (v2.float_complex_array_value () / v1.float_value ());
 }
@@ -107,9 +107,9 @@
 DEFBINOP (el_ldiv, float_scalar, float_complex_matrix)
 {
   const octave_float_scalar& v1
-    = dynamic_cast<const octave_float_scalar&> (a1);
+    = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
   const octave_float_complex_matrix& v2
-    = dynamic_cast<const octave_float_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_float_complex_matrix&> (a2);
 
   return octave_value (v2.float_complex_array_value () / v1.float_value ());
 }
@@ -130,7 +130,7 @@
 
 DEFCONV (float_complex_matrix_conv, float_scalar, float_complex_matrix)
 {
-  const octave_float_scalar& v = dynamic_cast<const octave_float_scalar&> (a);
+  const octave_float_scalar& v = DYNORSTAT_CAST<const octave_float_scalar&> (a);
 
   return new octave_float_complex_matrix (FloatComplexMatrix
                                             (v.float_matrix_value ()));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fs-fcs.cc
--- a/libinterp/operators/op-fs-fcs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fs-fcs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -50,8 +50,8 @@
 
 DEFBINOP (div, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v1.float_value () / v2.float_complex_value ());
 }
@@ -60,8 +60,8 @@
 
 DEFBINOP (ldiv, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v2.float_complex_value () / v1.float_value ());
 }
@@ -77,8 +77,8 @@
 
 DEFBINOP (el_div, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v1.float_value () / v2.float_complex_value ());
 }
@@ -87,16 +87,16 @@
 
 DEFBINOP (el_ldiv, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v2.float_complex_value () / v1.float_value ());
 }
 
 DEFBINOP (el_and, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v1.float_scalar_value ()
                        && (v2.float_complex_value () != 0.0f));
@@ -104,8 +104,8 @@
 
 DEFBINOP (el_or, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_complex& v2 = DYNORSTAT_CAST<const octave_float_complex&> (a2);
 
   return octave_value (v1.float_scalar_value ()
                        || (v2.float_complex_value () != 0.0f));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fs-fm.cc
--- a/libinterp/operators/op-fs-fm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fs-fm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -48,8 +48,8 @@
 
 DEFBINOP (div, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_matrix& v2 = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
 
   FloatMatrix m1 = v1.float_matrix_value ();
   FloatMatrix m2 = v2.float_matrix_value ();
@@ -65,8 +65,8 @@
 
 DEFBINOP (ldiv, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_matrix& v2 = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
 
   return octave_value (v2.float_array_value () / v1.float_value ());
 }
@@ -93,8 +93,8 @@
 
 DEFBINOP (el_ldiv, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_matrix& v2 = DYNORSTAT_CAST<const octave_float_matrix&> (a2);
 
   return octave_value (v2.float_array_value () / v1.float_value ());
 }
@@ -113,7 +113,7 @@
 
 DEFCONV (matrix_conv, float_scalar, float_matrix)
 {
-  const octave_float_scalar& v = dynamic_cast<const octave_float_scalar&> (a);
+  const octave_float_scalar& v = DYNORSTAT_CAST<const octave_float_scalar&> (a);
 
   return new octave_float_matrix (v.float_matrix_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-fs-fs.cc
--- a/libinterp/operators/op-fs-fs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-fs-fs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -46,7 +46,7 @@
 
 DEFUNOP (not, float_scalar)
 {
-  const octave_float_scalar& v = dynamic_cast<const octave_float_scalar&> (a);
+  const octave_float_scalar& v = DYNORSTAT_CAST<const octave_float_scalar&> (a);
   float x = v.float_value ();
   if (octave::math::isnan (x))
     octave::err_nan_to_logical_conversion ();
@@ -70,8 +70,8 @@
 
 DEFBINOP (div, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return octave_value (v1.float_value () / v2.float_value ());
 }
@@ -80,8 +80,8 @@
 
 DEFBINOP (ldiv, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return octave_value (v2.float_value () / v1.float_value ());
 }
@@ -97,8 +97,8 @@
 
 DEFBINOP (el_div, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return octave_value (v1.float_value () / v2.float_value ());
 }
@@ -107,8 +107,8 @@
 
 DEFBINOP (el_ldiv, float_scalar, 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);
+  const octave_float_scalar& v1 = DYNORSTAT_CAST<const octave_float_scalar&> (a1);
+  const octave_float_scalar& v2 = DYNORSTAT_CAST<const octave_float_scalar&> (a2);
 
   return octave_value (v2.float_value () / v1.float_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-int.h
--- a/libinterp/operators/op-int.h	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-int.h	Sun Nov 21 16:49:58 2021 +0100
@@ -36,8 +36,8 @@
   CONCAT2 (oct_binop_, name) (const octave_base_value& a1,              \
                               const octave_base_value& a2)              \
   {                                                                     \
-    const octave_ ## t1& v1 = dynamic_cast<const octave_ ## t1&> (a1);  \
-    const octave_ ## t2& v2 = dynamic_cast<const octave_ ## t2&> (a2);  \
+    const octave_ ## t1& v1 = DYNORSTAT_CAST<const octave_ ## t1&> (a1);  \
+    const octave_ ## t2& v2 = DYNORSTAT_CAST<const octave_ ## t2&> (a2);  \
     octave_value retval = octave_value                                  \
       (v1.t1 ## _value () op v2.t2 ## _value ());                       \
     return retval;                                                      \
@@ -48,8 +48,8 @@
   CONCAT2 (oct_binop_, name) (const octave_base_value& a1,              \
                               const octave_base_value& a2)              \
   {                                                                     \
-    const octave_ ## t1& v1 = dynamic_cast<const octave_ ## t1&> (a1);  \
-    const octave_ ## t2& v2 = dynamic_cast<const octave_ ## t2&> (a2);  \
+    const octave_ ## t1& v1 = DYNORSTAT_CAST<const octave_ ## t1&> (a1);  \
+    const octave_ ## t2& v2 = DYNORSTAT_CAST<const octave_ ## t2&> (a2);  \
     octave_value retval = octave_value                                  \
       (v1.e1 ## _value () op v2.e2 ## _value ());                       \
     return retval;                                                      \
@@ -60,8 +60,8 @@
   CONCAT2 (oct_binop_, name) (const octave_base_value& a1,              \
                               const octave_base_value& a2)              \
   {                                                                     \
-    const octave_ ## t1& v1 = dynamic_cast<const octave_ ## t1&> (a1);  \
-    const octave_ ## t2& v2 = dynamic_cast<const octave_ ## t2&> (a2);  \
+    const octave_ ## t1& v1 = DYNORSTAT_CAST<const octave_ ## t1&> (a1);  \
+    const octave_ ## t2& v2 = DYNORSTAT_CAST<const octave_ ## t2&> (a2);  \
     octave_value retval = octave_value (f (v1.t1 ## _value (), v2.t2 ## _value ())); \
     return retval;                                                      \
   }
@@ -71,8 +71,8 @@
   CONCAT2 (oct_binop_, name) (const octave_base_value& a1,              \
                               const octave_base_value& a2)              \
   {                                                                     \
-    const octave_ ## t1& v1 = dynamic_cast<const octave_ ## t1&> (a1);  \
-    const octave_ ## t2& v2 = dynamic_cast<const octave_ ## t2&> (a2);  \
+    const octave_ ## t1& v1 = DYNORSTAT_CAST<const octave_ ## t1&> (a1);  \
+    const octave_ ## t2& v2 = DYNORSTAT_CAST<const octave_ ## t2&> (a2);  \
     octave_value retval = octave_value (f (v1.e1 ## _value (), v2.e2 ## _value ())); \
     return retval;                                                      \
   }
@@ -179,7 +179,7 @@
   DEFUNOP_OP (s_uplus, TYPE ## _scalar, /* no-op */)                    \
   DEFUNOP (s_uminus, TYPE ## _scalar)                                   \
   {                                                                     \
-    const octave_ ## TYPE ## _scalar & v = dynamic_cast<const octave_ ## TYPE ## _scalar &> (a); \
+    const octave_ ## TYPE ## _scalar & v = DYNORSTAT_CAST<const octave_ ## TYPE ## _scalar &> (a); \
     octave_value retval = octave_value (- v. TYPE ## _scalar_value ()); \
     return retval;                                                      \
   }                                                                     \
@@ -198,8 +198,8 @@
                                                                         \
   DEFBINOP (PFX ## _div, T1 ## scalar, 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); \
+    const octave_ ## T1 ## scalar& v1 = DYNORSTAT_CAST<const octave_ ## T1 ## scalar&> (a1); \
+    const octave_ ## T2 ## scalar& v2 = DYNORSTAT_CAST<const octave_ ## T2 ## scalar&> (a2); \
                                                                         \
     return octave_value (v1.T1 ## scalar_value () / v2.T2 ## scalar_value ()); \
   }                                                                     \
@@ -208,8 +208,8 @@
                                                                         \
   DEFBINOP (PFX ## _ldiv, T1 ## scalar, 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); \
+    const octave_ ## T1 ## scalar& v1 = DYNORSTAT_CAST<const octave_ ## T1 ## scalar&> (a1); \
+    const octave_ ## T2 ## scalar& v2 = DYNORSTAT_CAST<const octave_ ## T2 ## scalar&> (a2); \
                                                                         \
     return octave_value (v2.T2 ## scalar_value () / v1.T1 ## scalar_value ()); \
   }                                                                     \
@@ -218,8 +218,8 @@
                                                                         \
   DEFBINOP (PFX ## _el_div, T1 ## scalar, 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); \
+    const octave_ ## T1 ## scalar& v1 = DYNORSTAT_CAST<const octave_ ## T1 ## scalar&> (a1); \
+    const octave_ ## T2 ## scalar& v2 = DYNORSTAT_CAST<const octave_ ## T2 ## scalar&> (a2); \
                                                                         \
     return octave_value (v1.T1 ## scalar_value () / v2.T2 ## scalar_value ()); \
   }                                                                     \
@@ -228,8 +228,8 @@
                                                                         \
   DEFBINOP (PFX ## _el_ldiv, T1 ## scalar, 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); \
+    const octave_ ## T1 ## scalar& v1 = DYNORSTAT_CAST<const octave_ ## T1 ## scalar&> (a1); \
+    const octave_ ## T2 ## scalar& v2 = DYNORSTAT_CAST<const octave_ ## T2 ## scalar&> (a2); \
                                                                         \
     return octave_value (v2.T2 ## scalar_value () / v1.T1 ## scalar_value ()); \
   }
@@ -237,16 +237,16 @@
 #define OCTAVE_SS_INT_BOOL_OPS(PFX, T1, T2, Z1, Z2)                     \
   DEFBINOP (PFX ## _el_and, T2, T2)                                     \
   {                                                                     \
-    const octave_ ## T1 ## scalar& v1 = dynamic_cast<const octave_ ## T1 ## scalar&> (a1); \
-    const octave_ ## T2 ## scalar& v2 = dynamic_cast<const octave_ ## T2 ## scalar&> (a2); \
+    const octave_ ## T1 ## scalar& v1 = DYNORSTAT_CAST<const octave_ ## T1 ## scalar&> (a1); \
+    const octave_ ## T2 ## scalar& v2 = DYNORSTAT_CAST<const octave_ ## T2 ## scalar&> (a2); \
                                                                         \
     return v1.T1 ## scalar_value () != Z1 && v2.T2 ## scalar_value () != Z2; \
   }                                                                     \
                                                                         \
   DEFBINOP (PFX ## _el_or, T1, T2)                                      \
   {                                                                     \
-    const octave_ ## T1 ## scalar& v1 = dynamic_cast<const octave_ ## T1 ## scalar&> (a1); \
-    const octave_ ## T2 ## scalar& v2 = dynamic_cast<const octave_ ## T2 ## scalar&> (a2); \
+    const octave_ ## T1 ## scalar& v1 = DYNORSTAT_CAST<const octave_ ## T1 ## scalar&> (a1); \
+    const octave_ ## T2 ## scalar& v2 = DYNORSTAT_CAST<const octave_ ## T2 ## scalar&> (a2); \
                                                                         \
     return v1.T1 ## scalar_value () != Z1 || v2.T2 ## scalar_value () != Z2; \
   }
@@ -318,8 +318,8 @@
                                                                         \
   /* DEFBINOP (PFX ## _div, TS ## scalar, 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); */ \
+  /* const octave_ ## TS ## scalar& v1 = DYNORSTAT_CAST<const octave_ ## TS ## scalar&> (a1); */ \
+  /* const octave_ ## TM ## matrix& v2 = DYNORSTAT_CAST<const octave_ ## TM ## matrix&> (a2); */ \
   /* */                                                                 \
   /* Matrix m1 = v1.TM ## matrix_value (); */                           \
   /* Matrix m2 = v2.TM ## matrix_value (); */                           \
@@ -331,8 +331,8 @@
                                                                         \
   DEFBINOP (PFX ## _ldiv, TS ## scalar, 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); \
+   const octave_ ## TS ## scalar& v1 = DYNORSTAT_CAST<const octave_ ## TS ## scalar&> (a1); \
+   const octave_ ## TM ## matrix& v2 = DYNORSTAT_CAST<const octave_ ## TM ## matrix&> (a2); \
                                                                         \
    return octave_value (v2.TM ## array_value () / v1.TS ## scalar_value ()); \
    }                                                                    \
@@ -340,8 +340,8 @@
   DEFINTNDBINOP_OP (PFX ## _el_mul, TS ## scalar, TM ## matrix, TS ## scalar, TM ## array, *, TI) \
   DEFBINOP (PFX ## _el_div, TS ## scalar, 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); \
+   const octave_ ## TS ## scalar& v1 = DYNORSTAT_CAST<const octave_ ## TS ## scalar&> (a1); \
+   const octave_ ## TM ## matrix& v2 = DYNORSTAT_CAST<const octave_ ## TM ## matrix&> (a2); \
                                                                         \
    octave_value retval = octave_value (v1.TS ## scalar_value () / v2.TM ## array_value ()); \
    return retval;                                                       \
@@ -351,8 +351,8 @@
                                                                         \
   DEFBINOP (PFX ## _el_ldiv, TS ## scalar, 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); \
+   const octave_ ## TS ## scalar& v1 = DYNORSTAT_CAST<const octave_ ## TS ## scalar&> (a1); \
+   const octave_ ## TM ## matrix& v2 = DYNORSTAT_CAST<const octave_ ## TM ## matrix&> (a2); \
                                                                         \
    return octave_value (v2.TM ## array_value () / v1.TS ## scalar_value ()); \
    }
@@ -435,7 +435,7 @@
 #define OCTAVE_SM_CONV(TS, TM)                                          \
   DEFCONV (TS ## s_ ## TM ## m_conv, TM ## scalar, TM ## matrix)        \
   {                                                                     \
-    const octave_ ## TS ## scalar& v = dynamic_cast<const octave_ ## TS ## scalar&> (a); \
+    const octave_ ## TS ## scalar& v = DYNORSTAT_CAST<const octave_ ## TS ## scalar&> (a); \
                                                                         \
     return new octave_ ## TM ## matrix (v.TM ## array_value ());        \
   }
@@ -470,8 +470,8 @@
                                                                         \
   DEFBINOP (PFX ## _div, TM ## matrix, 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); \
+    const octave_ ## TM ## matrix& v1 = DYNORSTAT_CAST<const octave_ ## TM ## matrix&> (a1); \
+    const octave_ ## TS ## scalar& v2 = DYNORSTAT_CAST<const octave_ ## TS ## scalar&> (a2); \
                                                                         \
     return octave_value (v1.TM ## array_value () / v2.TS ## scalar_value ()); \
   }                                                                     \
@@ -480,8 +480,8 @@
                                                                         \
   /* DEFBINOP (PFX ## _ldiv, TM ## matrix, 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); */ \
+  /* const octave_ ## TM ## matrix& v1 = DYNORSTAT_CAST<const octave_ ## TM ## matrix&> (a1); */ \
+  /* const octave_ ## TS ## scalar& v2 = DYNORSTAT_CAST<const octave_ ## TS ## scalar&> (a2); */ \
   /* */                                                                 \
   /* Matrix m1 = v1.TM ## matrix_value (); */                           \
   /* Matrix m2 = v2.TM ## matrix_value (); */                           \
@@ -493,8 +493,8 @@
                                                                         \
   DEFBINOP (PFX ## _el_div, TM ## matrix, 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); \
+    const octave_ ## TM ## matrix& v1 = DYNORSTAT_CAST<const octave_ ## TM ## matrix&> (a1); \
+    const octave_ ## TS ## scalar& v2 = DYNORSTAT_CAST<const octave_ ## TS ## scalar&> (a2); \
                                                                         \
     return octave_value (v1.TM ## array_value () / v2.TS ## scalar_value ()); \
   }                                                                     \
@@ -503,8 +503,8 @@
                                                                         \
   DEFBINOP (PFX ## _el_ldiv, TM ## matrix, 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); \
+    const octave_ ## TM ## matrix& v1 = DYNORSTAT_CAST<const octave_ ## TM ## matrix&> (a1); \
+    const octave_ ## TS ## scalar& v2 = DYNORSTAT_CAST<const octave_ ## TS ## scalar&> (a2); \
                                                                         \
     octave_value retval = v2.TS ## scalar_value () / v1.TM ## array_value (); \
     return retval;                                                      \
@@ -623,14 +623,14 @@
   DEFNDUNOP_OP (m_uplus, TYPE ## _matrix, TYPE ## _array, /* no-op */)  \
   DEFUNOP (m_uminus, TYPE ## _matrix)                                   \
   {                                                                     \
-    const octave_ ## TYPE ## _matrix & v = dynamic_cast<const octave_ ## TYPE ## _matrix &> (a); \
+    const octave_ ## TYPE ## _matrix & v = DYNORSTAT_CAST<const octave_ ## TYPE ## _matrix &> (a); \
     octave_value retval = octave_value (- v. TYPE ## _array_value ());  \
     return retval;                                                      \
   }                                                                     \
                                                                         \
   DEFUNOP (m_transpose, TYPE ## _matrix)                                \
   {                                                                     \
-    const octave_ ## TYPE ## _matrix& v = dynamic_cast<const octave_ ## TYPE ## _matrix&> (a); \
+    const octave_ ## TYPE ## _matrix& v = DYNORSTAT_CAST<const octave_ ## TYPE ## _matrix&> (a); \
                                                                         \
     if (v.ndims () > 2)                                                 \
       error ("transpose not defined for N-D objects");                  \
@@ -666,8 +666,8 @@
                                                                         \
   DEFBINOP (PFX ## _el_ldiv, T1 ## matrix, 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); \
+    const octave_ ## T1 ## matrix& v1 = DYNORSTAT_CAST<const octave_ ## T1 ## matrix&> (a1); \
+    const octave_ ## T2 ## matrix& v2 = DYNORSTAT_CAST<const octave_ ## T2 ## matrix&> (a2); \
                                                                         \
     octave_value retval = octave_value (quotient (v2.T2 ## array_value (), v1.T1 ## array_value ())); \
     return retval;                                                      \
@@ -807,7 +807,7 @@
 #define OCTAVE_MM_CONV(T1, T2)                                          \
   DEFCONV (T1 ## m_ ## T2 ## m_conv, T1 ## matrix, T2 ## matrix)        \
   {                                                                     \
-    const octave_ ## T1 ## matrix& v = dynamic_cast<const octave_ ## T1 ## matrix&> (a); \
+    const octave_ ## T1 ## matrix& v = DYNORSTAT_CAST<const octave_ ## T1 ## matrix&> (a); \
                                                                         \
     return new octave_ ## T2 ## matrix (v.T2 ## array_value ());        \
   }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-m-cm.cc
--- a/libinterp/operators/op-m-cm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-m-cm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -55,9 +55,9 @@
 
 DEFBINOP (trans_mul, matrix, complex_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   Matrix m1 = v1.matrix_value ();
   ComplexMatrix m2 = v2.complex_matrix_value ();
@@ -68,9 +68,9 @@
 
 DEFBINOP (div, matrix, complex_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   ComplexMatrix ret = xdiv (v1.matrix_value (),
@@ -87,9 +87,9 @@
 
 DEFBINOP (ldiv, matrix, complex_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.matrix_value (),
@@ -101,9 +101,9 @@
 
 DEFBINOP (trans_ldiv, matrix, complex_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.matrix_value (),
@@ -126,9 +126,9 @@
 
 DEFBINOP (el_ldiv, matrix, complex_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   return quotient (v2.complex_array_value (), v1.array_value ());
 }
@@ -140,7 +140,7 @@
 
 DEFCONV (complex_matrix_conv, matrix, complex_matrix)
 {
-  const octave_matrix& v = dynamic_cast<const octave_matrix&> (a);
+  const octave_matrix& v = DYNORSTAT_CAST<const octave_matrix&> (a);
 
   return new octave_complex_matrix (ComplexNDArray (v.array_value ()));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-m-cs.cc
--- a/libinterp/operators/op-m-cs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-m-cs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -54,8 +54,8 @@
 
 DEFBINOP (div, matrix, complex)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.array_value () / v2.complex_value ());
 }
@@ -64,8 +64,8 @@
 
 DEFBINOP (ldiv, matrix, complex)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   Matrix m1 = v1.matrix_value ();
   ComplexMatrix m2 = v2.complex_matrix_value ();
@@ -88,8 +88,8 @@
 
 DEFBINOP (el_div, matrix, complex)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.array_value () / v2.complex_value ());
 }
@@ -98,8 +98,8 @@
 
 DEFBINOP (el_ldiv, matrix, complex)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return elem_xdiv (v2.complex_value (), v1.array_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-m-m.cc
--- a/libinterp/operators/op-m-m.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-m-m.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -48,7 +48,7 @@
 
 DEFUNOP (transpose, matrix)
 {
-  const octave_matrix& v = dynamic_cast<const octave_matrix&> (a);
+  const octave_matrix& v = DYNORSTAT_CAST<const octave_matrix&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -69,8 +69,8 @@
 
 DEFBINOP (div, matrix, matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   Matrix ret = xdiv (v1.matrix_value (), v2.matrix_value (), typ);
@@ -86,8 +86,8 @@
 
 DEFBINOP (ldiv, matrix, matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   Matrix ret = xleftdiv (v1.matrix_value (), v2.matrix_value (), typ);
@@ -98,24 +98,24 @@
 
 DEFBINOP (trans_mul, matrix, matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_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)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_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)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   Matrix ret = xleftdiv (v1.matrix_value (), v2.matrix_value (),
@@ -138,8 +138,8 @@
 
 DEFBINOP (el_ldiv, matrix, matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   return octave_value (quotient (v2.array_value (), v1.array_value ()));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-m-s.cc
--- a/libinterp/operators/op-m-s.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-m-s.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -48,8 +48,8 @@
 
 DEFBINOP (div, matrix, scalar)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v1.array_value () / v2.double_value ());
 }
@@ -58,8 +58,8 @@
 
 DEFBINOP (ldiv, matrix, scalar)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   Matrix m1 = v1.matrix_value ();
   Matrix m2 = v2.matrix_value ();
@@ -82,8 +82,8 @@
 
 DEFBINOP (el_div, matrix, scalar)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v1.array_value () / v2.double_value ());
 }
@@ -92,8 +92,8 @@
 
 DEFBINOP (el_ldiv, matrix, scalar)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return elem_xdiv (v2.double_value (), v1.array_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-m-scm.cc
--- a/libinterp/operators/op-m-scm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-m-scm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -52,9 +52,9 @@
 
 DEFBINOP (div, matrix, sparse_complex_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (v1.array_value () / v2.complex_value ());
@@ -77,9 +77,9 @@
 
 DEFBINOP (ldiv, matrix, sparse_complex_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   ComplexMatrix ret = xleftdiv (v1.matrix_value (),
@@ -101,9 +101,9 @@
 
 DEFBINOP (el_pow, matrix, sparse_complex_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value
          (elem_xpow (SparseMatrix (v1.matrix_value ()),
@@ -112,9 +112,9 @@
 
 DEFBINOP (el_ldiv, matrix, sparse_complex_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
   return octave_value
          (quotient (v2.sparse_complex_matrix_value (), v1.matrix_value ()));
 }
@@ -124,9 +124,9 @@
 
 DEFCATOP (m_scm, matrix, sparse_complex_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
   SparseMatrix tmp (v1.matrix_value ());
   return octave_value (tmp. concat (v2.sparse_complex_matrix_value (),
                                     ra_idx));
@@ -134,7 +134,7 @@
 
 DEFCONV (sparse_complex_matrix_conv, matrix, sparse_complex_matrix)
 {
-  const octave_matrix& v = dynamic_cast<const octave_matrix&> (a);
+  const octave_matrix& v = DYNORSTAT_CAST<const octave_matrix&> (a);
   return new octave_sparse_complex_matrix
          (SparseComplexMatrix (v.complex_matrix_value ()));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-m-sm.cc
--- a/libinterp/operators/op-m-sm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-m-sm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -51,8 +51,8 @@
 
 DEFBINOP (div, matrix, sparse_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (v1.array_value () / v2.scalar_value ());
@@ -74,8 +74,8 @@
 
 DEFBINOP (ldiv, matrix, sparse_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
   MatrixType typ = v1.matrix_type ();
 
   Matrix ret = xleftdiv (v1.matrix_value (), v2.matrix_value (), typ);
@@ -98,8 +98,8 @@
 
 DEFBINOP (el_pow, matrix, sparse_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   return octave_value (elem_xpow (SparseMatrix (v1.matrix_value ()),
                                   v2.sparse_matrix_value ()));
@@ -107,8 +107,8 @@
 
 DEFBINOP (el_ldiv, matrix, sparse_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   return octave_value
          (quotient (v2.sparse_matrix_value (), v1.matrix_value ()));
@@ -119,15 +119,15 @@
 
 DEFCATOP (m_sm, matrix, sparse_matrix)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_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)
 {
-  const octave_matrix& v = dynamic_cast<const octave_matrix&> (a);
+  const octave_matrix& v = DYNORSTAT_CAST<const octave_matrix&> (a);
   return new octave_sparse_matrix (SparseMatrix (v.matrix_value ()));
 }
 
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-mi.cc
--- a/libinterp/operators/op-mi.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-mi.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -47,7 +47,7 @@
 static octave_value
 oct_unop_unsigned_uplus (const octave_base_value& a)
 {
-  const octave_magic_uint& v = dynamic_cast<const octave_magic_uint&> (a);
+  const octave_magic_uint& v = DYNORSTAT_CAST<const octave_magic_uint&> (a);
   // no-op.
   // FIXME: but can we do this just by incrementing the reference count?
   return octave_value (v.clone ());
@@ -56,7 +56,7 @@
 static octave_value
 oct_unop_unsigned_uminus (const octave_base_value& a)
 {
-  const octave_magic_uint& v = dynamic_cast<const octave_magic_uint&> (a);
+  const octave_magic_uint& v = DYNORSTAT_CAST<const octave_magic_uint&> (a);
 
   // We are storing a uint64 value, so some fakery is needed here.
   // Is there a better way?
@@ -96,7 +96,7 @@
 static octave_value
 oct_unop_signed_uplus (const octave_base_value& a)
 {
-  const octave_magic_int& v = dynamic_cast<const octave_magic_int&> (a);
+  const octave_magic_int& v = DYNORSTAT_CAST<const octave_magic_int&> (a);
   // no-op.
   // FIXME: but can we do this just by incrementing the reference count?
   return octave_value (v.clone ());
@@ -105,7 +105,7 @@
 static octave_value
 oct_unop_signed_uminus (const octave_base_value& a)
 {
-  const octave_magic_int& v = dynamic_cast<const octave_magic_int&> (a);
+  const octave_magic_int& v = DYNORSTAT_CAST<const octave_magic_int&> (a);
 
   // FIXME: Maybe there should also be octave_magic_int::as_TYPE_value
   // functions?
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-pm-pm.cc
--- a/libinterp/operators/op-pm-pm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-pm-pm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -41,7 +41,7 @@
 
 DEFUNOP (transpose, perm_matrix)
 {
-  const octave_perm_matrix& v = dynamic_cast<const octave_perm_matrix&> (a);
+  const octave_perm_matrix& v = DYNORSTAT_CAST<const octave_perm_matrix&> (a);
   return octave_value (v.perm_matrix_value ().transpose ());
 }
 
@@ -49,31 +49,31 @@
 
 DEFBINOP (div, perm_matrix, 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);
+  const octave_perm_matrix& v1 = DYNORSTAT_CAST<const octave_perm_matrix&> (a1);
+  const octave_perm_matrix& v2 = DYNORSTAT_CAST<const octave_perm_matrix&> (a2);
 
   return (v1.perm_matrix_value () * v2.perm_matrix_value ().inverse ());
 }
 
 DEFBINOP (ldiv, perm_matrix, 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);
+  const octave_perm_matrix& v1 = DYNORSTAT_CAST<const octave_perm_matrix&> (a1);
+  const octave_perm_matrix& v2 = DYNORSTAT_CAST<const octave_perm_matrix&> (a2);
 
   return (v1.perm_matrix_value ().inverse () * v2.perm_matrix_value ());
 }
 
 DEFBINOP (pow, perm_matrix, scalar)
 {
-  const octave_perm_matrix& v1 = dynamic_cast<const octave_perm_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_perm_matrix& v1 = DYNORSTAT_CAST<const octave_perm_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return xpow (v1.perm_matrix_value (), v2.scalar_value ());
 }
 
 CONVDECL (perm_matrix_to_matrix)
 {
-  const octave_perm_matrix& v = dynamic_cast<const octave_perm_matrix&> (a);
+  const octave_perm_matrix& v = DYNORSTAT_CAST<const octave_perm_matrix&> (a);
 
   return new octave_matrix (v.matrix_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-pm-scm.cc
--- a/libinterp/operators/op-pm-scm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-pm-scm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -42,9 +42,9 @@
 
 DEFBINOP (mul_pm_scm, perm_matrix, sparse_complex_matrix)
 {
-  const octave_perm_matrix& v1 = dynamic_cast<const octave_perm_matrix&> (a1);
+  const octave_perm_matrix& v1 = DYNORSTAT_CAST<const octave_perm_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -60,9 +60,9 @@
 
 DEFBINOP (ldiv_pm_scm, perm_matrix, sparse_complex_matrix)
 {
-  const octave_perm_matrix& v1 = dynamic_cast<const octave_perm_matrix&> (a1);
+  const octave_perm_matrix& v1 = DYNORSTAT_CAST<const octave_perm_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   return v1.perm_matrix_value ().inverse () * v2.sparse_complex_matrix_value ();
 }
@@ -72,8 +72,8 @@
 DEFBINOP (mul_scm_pm, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_perm_matrix& v2 = DYNORSTAT_CAST<const octave_perm_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -90,8 +90,8 @@
 DEFBINOP (div_scm_pm, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_perm_matrix& v2 = DYNORSTAT_CAST<const octave_perm_matrix&> (a2);
 
   return v1.sparse_complex_matrix_value () * v2.perm_matrix_value ().inverse ();
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-pm-sm.cc
--- a/libinterp/operators/op-pm-sm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-pm-sm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -42,8 +42,8 @@
 
 DEFBINOP (mul_pm_sm, perm_matrix, 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);
+  const octave_perm_matrix& v1 = DYNORSTAT_CAST<const octave_perm_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     {
@@ -59,8 +59,8 @@
 
 DEFBINOP (ldiv_pm_sm, perm_matrix, 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);
+  const octave_perm_matrix& v1 = DYNORSTAT_CAST<const octave_perm_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   return v1.perm_matrix_value ().inverse () * v2.sparse_matrix_value ();
 }
@@ -69,8 +69,8 @@
 
 DEFBINOP (mul_sm_pm, sparse_matrix, 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);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_perm_matrix& v2 = DYNORSTAT_CAST<const octave_perm_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     {
@@ -86,8 +86,8 @@
 
 DEFBINOP (div_sm_pm, sparse_matrix, 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);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_perm_matrix& v2 = DYNORSTAT_CAST<const octave_perm_matrix&> (a2);
 
   return v1.sparse_matrix_value () * v2.perm_matrix_value ().inverse ();
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-pm-template.cc
--- a/libinterp/operators/op-pm-template.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-pm-template.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -57,8 +57,8 @@
 
 DEFBINOP (mul, LMATRIX, RMATRIX)
 {
-  const OCTAVE_LMATRIX& v1 = dynamic_cast<const OCTAVE_LMATRIX&> (a1);
-  const OCTAVE_RMATRIX& v2 = dynamic_cast<const OCTAVE_RMATRIX&> (a2);
+  const OCTAVE_LMATRIX& v1 = DYNORSTAT_CAST<const OCTAVE_LMATRIX&> (a1);
+  const OCTAVE_RMATRIX& v2 = DYNORSTAT_CAST<const OCTAVE_RMATRIX&> (a2);
 
   return v1.LMATRIX_VALUE () * v2.RMATRIX_VALUE ();
 }
@@ -66,16 +66,16 @@
 #if defined (LEFT)
 DEFBINOP (ldiv, LMATRIX, RMATRIX)
 {
-  const OCTAVE_LMATRIX& v1 = dynamic_cast<const OCTAVE_LMATRIX&> (a1);
-  const OCTAVE_RMATRIX& v2 = dynamic_cast<const OCTAVE_RMATRIX&> (a2);
+  const OCTAVE_LMATRIX& v1 = DYNORSTAT_CAST<const OCTAVE_LMATRIX&> (a1);
+  const OCTAVE_RMATRIX& v2 = DYNORSTAT_CAST<const OCTAVE_RMATRIX&> (a2);
 
   return v1.perm_matrix_value ().inverse () * v2.RMATRIX_VALUE ();
 }
 #else
 DEFBINOP (div, LMATRIX, RMATRIX)
 {
-  const OCTAVE_LMATRIX& v1 = dynamic_cast<const OCTAVE_LMATRIX&> (a1);
-  const OCTAVE_RMATRIX& v2 = dynamic_cast<const OCTAVE_RMATRIX&> (a2);
+  const OCTAVE_LMATRIX& v1 = DYNORSTAT_CAST<const OCTAVE_LMATRIX&> (a1);
+  const OCTAVE_RMATRIX& v2 = DYNORSTAT_CAST<const OCTAVE_RMATRIX&> (a2);
 
   return v1.LMATRIX_VALUE () * v2.perm_matrix_value ().inverse ();
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-range.cc
--- a/libinterp/operators/op-range.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-range.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -43,7 +43,7 @@
 
 CONVDECL (range_to_matrix)
 {
-  const octave_range& v = dynamic_cast<const octave_range&> (a);
+  const octave_range& v = DYNORSTAT_CAST<const octave_range&> (a);
 
   return new octave_matrix (v.array_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-s-cm.cc
--- a/libinterp/operators/op-s-cm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-s-cm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -54,9 +54,9 @@
 
 DEFBINOP (div, scalar, complex_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   Matrix m1 = v1.matrix_value ();
   ComplexMatrix m2 = v2.complex_matrix_value ();
@@ -72,9 +72,9 @@
 
 DEFBINOP (ldiv, scalar, complex_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   return octave_value (v2.complex_array_value () / v1.double_value ());
 }
@@ -92,9 +92,9 @@
 
 DEFBINOP (el_ldiv, scalar, complex_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   return octave_value (v2.complex_array_value () / v1.double_value ());
 }
@@ -106,7 +106,7 @@
 
 DEFCONV (complex_matrix_conv, scalar, complex_matrix)
 {
-  const octave_scalar& v = dynamic_cast<const octave_scalar&> (a);
+  const octave_scalar& v = DYNORSTAT_CAST<const octave_scalar&> (a);
 
   return new octave_complex_matrix (ComplexMatrix (v.matrix_value ()));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-s-cs.cc
--- a/libinterp/operators/op-s-cs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-s-cs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -49,8 +49,8 @@
 
 DEFBINOP (div, scalar, complex)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.double_value () / v2.complex_value ());
 }
@@ -59,8 +59,8 @@
 
 DEFBINOP (ldiv, scalar, complex)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v2.complex_value () / v1.double_value ());
 }
@@ -76,8 +76,8 @@
 
 DEFBINOP (el_div, scalar, complex)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.double_value () / v2.complex_value ());
 }
@@ -86,24 +86,24 @@
 
 DEFBINOP (el_ldiv, scalar, complex)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v2.complex_value () / v1.double_value ());
 }
 
 DEFBINOP (el_and, scalar, complex)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.double_value () && (v2.complex_value () != 0.0));
 }
 
 DEFBINOP (el_or, scalar, complex)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.double_value () || (v2.complex_value () != 0.0));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-s-m.cc
--- a/libinterp/operators/op-s-m.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-s-m.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -48,8 +48,8 @@
 
 DEFBINOP (div, scalar, matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   Matrix m1 = v1.matrix_value ();
   Matrix m2 = v2.matrix_value ();
@@ -65,8 +65,8 @@
 
 DEFBINOP (ldiv, scalar, matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   return octave_value (v2.array_value () / v1.double_value ());
 }
@@ -84,8 +84,8 @@
 
 DEFBINOP (el_ldiv, scalar, matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   return octave_value (v2.array_value () / v1.double_value ());
 }
@@ -97,7 +97,7 @@
 
 DEFCONV (matrix_conv, scalar, matrix)
 {
-  const octave_scalar& v = dynamic_cast<const octave_scalar&> (a);
+  const octave_scalar& v = DYNORSTAT_CAST<const octave_scalar&> (a);
 
   return new octave_matrix (v.matrix_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-s-s.cc
--- a/libinterp/operators/op-s-s.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-s-s.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -47,7 +47,7 @@
 
 DEFUNOP (not, scalar)
 {
-  const octave_scalar& v = dynamic_cast<const octave_scalar&> (a);
+  const octave_scalar& v = DYNORSTAT_CAST<const octave_scalar&> (a);
   double x = v.scalar_value ();
   if (octave::math::isnan (x))
     octave::err_nan_to_logical_conversion ();
@@ -71,8 +71,8 @@
 
 DEFBINOP (div, scalar, scalar)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v1.double_value () / v2.double_value ());
 }
@@ -81,8 +81,8 @@
 
 DEFBINOP (ldiv, scalar, scalar)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v2.double_value () / v1.double_value ());
 }
@@ -98,8 +98,8 @@
 
 DEFBINOP (el_div, scalar, scalar)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v1.double_value () / v2.double_value ());
 }
@@ -108,8 +108,8 @@
 
 DEFBINOP (el_ldiv, scalar, scalar)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v2.double_value () / v1.double_value ());
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-s-scm.cc
--- a/libinterp/operators/op-s-scm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-s-scm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -52,9 +52,9 @@
 
 DEFBINOP (div, scalar, sparse_complex_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (SparseComplexMatrix (1, 1, v1.scalar_value ()
@@ -72,17 +72,17 @@
 
 DEFBINOP (pow, scalar, sparse_complex_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
   return xpow (v1.scalar_value (), v2.complex_matrix_value ());
 }
 
 DEFBINOP (ldiv, scalar, sparse_complex_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value (v2.sparse_complex_matrix_value () / v1.double_value ());
 }
@@ -100,9 +100,9 @@
 
 DEFBINOP (el_ldiv, scalar, sparse_complex_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value (v2.sparse_complex_matrix_value () / v1.double_value ());
 }
@@ -112,9 +112,9 @@
 
 DEFCATOP (s_scm, scalar, sparse_compelx_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_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));
@@ -122,7 +122,7 @@
 
 DEFCONV (sparse_complex_matrix_conv, scalar, sparse_complex_matrix)
 {
-  const octave_scalar& v = dynamic_cast<const octave_scalar&> (a);
+  const octave_scalar& v = DYNORSTAT_CAST<const octave_scalar&> (a);
 
   return new octave_sparse_complex_matrix
          (SparseComplexMatrix (v.complex_matrix_value ()));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-s-sm.cc
--- a/libinterp/operators/op-s-sm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-s-sm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -48,8 +48,8 @@
 
 DEFBINOP (div, scalar, sparse_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (SparseMatrix (1, 1, v1.scalar_value () / v2.scalar_value ()));
@@ -66,15 +66,15 @@
 
 DEFBINOP (pow, scalar, sparse_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
   return xpow (v1.scalar_value (), v2.matrix_value ());
 }
 
 DEFBINOP (ldiv, scalar, sparse_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   return octave_value (v2.sparse_matrix_value () / v1.double_value ());
 }
@@ -92,8 +92,8 @@
 
 DEFBINOP (el_ldiv, scalar, sparse_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   return octave_value (v2.sparse_matrix_value () / v1.double_value ());
 }
@@ -103,15 +103,15 @@
 
 DEFCATOP (s_sm, scalar, sparse_matrix)
 {
-  const octave_scalar& v1 = dynamic_cast<const octave_scalar&> (a1);
-  const octave_sparse_matrix& v2 = dynamic_cast<const octave_sparse_matrix&> (a2);
+  const octave_scalar& v1 = DYNORSTAT_CAST<const octave_scalar&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_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)
 {
-  const octave_scalar& v = dynamic_cast<const octave_scalar&> (a);
+  const octave_scalar& v = DYNORSTAT_CAST<const octave_scalar&> (a);
 
   return new octave_sparse_matrix (SparseMatrix (v.matrix_value ()));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-sbm-b.cc
--- a/libinterp/operators/op-sbm-b.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-sbm-b.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -58,8 +58,8 @@
 
 DEFCATOP (sbm_b, sparse_bool_matrix, bool)
 {
-  const octave_sparse_bool_matrix& v1 = dynamic_cast<const octave_sparse_bool_matrix&> (a1);
-  const octave_bool& v2 = dynamic_cast<const octave_bool&> (a2);
+  const octave_sparse_bool_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_bool_matrix&> (a1);
+  const octave_bool& v2 = DYNORSTAT_CAST<const octave_bool&> (a2);
 
   SparseBoolMatrix tmp (1, 1, v2.bool_value ());
   return octave_value (v1.sparse_bool_matrix_value (). concat (tmp, ra_idx));
@@ -67,8 +67,8 @@
 
 DEFCATOP (sm_b, sparse_matrix, bool)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_bool& v2 = dynamic_cast<const octave_bool&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_bool& v2 = DYNORSTAT_CAST<const octave_bool&> (a2);
 
   SparseMatrix tmp (1, 1, v2.scalar_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
@@ -76,8 +76,8 @@
 
 DEFCATOP (sbm_s, sparse_bool_matrix, scalar)
 {
-  const octave_sparse_bool_matrix& v1 = dynamic_cast<const octave_sparse_bool_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_sparse_bool_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_bool_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   SparseMatrix tmp (1, 1, v2.scalar_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
@@ -85,8 +85,8 @@
 
 DEFASSIGNOP (assign, sparse_bool_matrix, bool)
 {
-  octave_sparse_bool_matrix& v1 = dynamic_cast<octave_sparse_bool_matrix&> (a1);
-  const octave_bool& v2 = dynamic_cast<const octave_bool&> (a2);
+  octave_sparse_bool_matrix& v1 = DYNORSTAT_CAST<octave_sparse_bool_matrix&> (a1);
+  const octave_bool& v2 = DYNORSTAT_CAST<const octave_bool&> (a2);
 
   SparseBoolMatrix tmp (1, 1, v2.bool_value ());
   v1.assign (idx, tmp);
@@ -98,7 +98,7 @@
                               const octave_value_list& idx,
                               const octave_base_value& a2)
 {
-  octave_sparse_bool_matrix& v1 = dynamic_cast<octave_sparse_bool_matrix&> (a1);
+  octave_sparse_bool_matrix& v1 = DYNORSTAT_CAST<octave_sparse_bool_matrix&> (a1);
 
   // FIXME: perhaps add a warning for this conversion if the values
   // are not all 0 or 1?
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-sbm-bm.cc
--- a/libinterp/operators/op-sbm-bm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-sbm-bm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -63,8 +63,8 @@
 
 DEFCATOP (sbm_bm, sparse_bool_matrix, bool_matrix)
 {
-  const octave_sparse_bool_matrix& v1 = dynamic_cast<const octave_sparse_bool_matrix&> (a1);
-  const octave_bool_matrix& v2 = dynamic_cast<const octave_bool_matrix&> (a2);
+  const octave_sparse_bool_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_bool_matrix&> (a1);
+  const octave_bool_matrix& v2 = DYNORSTAT_CAST<const octave_bool_matrix&> (a2);
 
   SparseBoolMatrix tmp (v2.bool_matrix_value ());
   return octave_value (v1.sparse_bool_matrix_value (). concat (tmp, ra_idx));
@@ -72,8 +72,8 @@
 
 DEFCATOP (sbm_m, sparse_bool_matrix, matrix)
 {
-  const octave_sparse_bool_matrix& v1 = dynamic_cast<const octave_sparse_bool_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_sparse_bool_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_bool_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   SparseMatrix tmp (v2.matrix_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
@@ -81,8 +81,8 @@
 
 DEFCATOP (sm_bm, sparse_matrix, bool_matrix)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_bool_matrix& v2 = dynamic_cast<const octave_bool_matrix&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_bool_matrix& v2 = DYNORSTAT_CAST<const octave_bool_matrix&> (a2);
 
   SparseMatrix tmp (v2.matrix_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
@@ -90,8 +90,8 @@
 
 DEFASSIGNOP (assign, sparse_bool_matrix, 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);
+  octave_sparse_bool_matrix& v1 = DYNORSTAT_CAST<octave_sparse_bool_matrix&> (a1);
+  const octave_bool_matrix& v2 = DYNORSTAT_CAST<const octave_bool_matrix&> (a2);
 
   v1.assign (idx, SparseBoolMatrix (v2.bool_matrix_value ()));
   return octave_value ();
@@ -104,7 +104,7 @@
                               const octave_value_list& idx,
                               const octave_base_value& a2)
 {
-  octave_sparse_bool_matrix& v1 = dynamic_cast<octave_sparse_bool_matrix&> (a1);
+  octave_sparse_bool_matrix& v1 = DYNORSTAT_CAST<octave_sparse_bool_matrix&> (a1);
 
   // FIXME: perhaps add a warning for this conversion if the values
   // are not all 0 or 1?
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-sbm-sbm.cc
--- a/libinterp/operators/op-sbm-sbm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-sbm-sbm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -47,21 +47,21 @@
 DEFUNOP (uplus, sparse_bool_matrix)
 {
   const octave_sparse_bool_matrix& v
-    = dynamic_cast<const octave_sparse_bool_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_sparse_bool_matrix&> (a);
   return octave_value (v.sparse_matrix_value ());
 }
 
 DEFUNOP (uminus, sparse_bool_matrix)
 {
   const octave_sparse_bool_matrix& v
-    = dynamic_cast<const octave_sparse_bool_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_sparse_bool_matrix&> (a);
   return octave_value (- v.sparse_matrix_value ());
 }
 
 DEFUNOP (transpose, sparse_bool_matrix)
 {
   const octave_sparse_bool_matrix& v
-    = dynamic_cast<const octave_sparse_bool_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_sparse_bool_matrix&> (a);
   return octave_value (v.sparse_bool_matrix_value ().transpose ());
 }
 
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-scm-cm.cc
--- a/libinterp/operators/op-scm-cm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-scm-cm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -53,9 +53,9 @@
 DEFBINOP (div, sparse_complex_matrix, complex_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   ComplexMatrix ret = xdiv (v1.complex_matrix_value (),
@@ -73,9 +73,9 @@
 DEFBINOP (ldiv, sparse_complex_matrix, complex_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     return octave_value (v2.complex_array_value () / v1.complex_value ());
@@ -107,9 +107,9 @@
 DEFBINOP (el_pow, sparse_complex_matrix, complex_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   return octave_value
          (elem_xpow (v1.sparse_complex_matrix_value (), SparseComplexMatrix
@@ -119,9 +119,9 @@
 DEFBINOP (el_ldiv, sparse_complex_matrix, matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   return octave_value (quotient (v2.complex_matrix_value (),
                                  v1.sparse_complex_matrix_value ()));
@@ -133,9 +133,9 @@
 DEFCATOP (scm_cm, sparse_complex_matrix, complex_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   SparseComplexMatrix tmp (v2.complex_matrix_value ());
   return octave_value
          (v1.sparse_complex_matrix_value ().concat (tmp, ra_idx));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-scm-cs.cc
--- a/libinterp/operators/op-scm-cs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-scm-cs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -51,8 +51,8 @@
 DEFBINOP (div, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.sparse_complex_matrix_value () / v2.complex_value ());
 }
@@ -60,16 +60,16 @@
 DEFBINOP (pow, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
   return xpow (v1.complex_matrix_value (), v2.complex_value ());
 }
 
 DEFBINOP (ldiv, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     return octave_value (SparseComplexMatrix (1, 1, v2.complex_value ()
@@ -97,8 +97,8 @@
 DEFBINOP (el_div, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.sparse_complex_matrix_value () / v2.complex_value ());
 }
@@ -108,8 +108,8 @@
 DEFBINOP (el_ldiv, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value
          (elem_xdiv (v2.complex_value (), v1.sparse_complex_matrix_value ()));
@@ -121,8 +121,8 @@
 DEFCATOP (scm_cs, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
   SparseComplexMatrix tmp (1, 1, v2.complex_value ());
   return octave_value
          (v1.sparse_complex_matrix_value ().concat (tmp, ra_idx));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-scm-m.cc
--- a/libinterp/operators/op-scm-m.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-scm-m.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -54,8 +54,8 @@
 DEFBINOP (div, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   ComplexMatrix ret = xdiv (v1.complex_matrix_value (),
@@ -73,8 +73,8 @@
 DEFBINOP (ldiv, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     return octave_value (v2.array_value () / v1.complex_value ());
@@ -103,8 +103,8 @@
 DEFBINOP (el_pow, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   return octave_value
          (elem_xpow (v1.sparse_complex_matrix_value (), SparseMatrix
@@ -114,8 +114,8 @@
 DEFBINOP (el_ldiv, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   return octave_value
          (quotient (v2.matrix_value (), v1.sparse_complex_matrix_value ()));
@@ -127,8 +127,8 @@
 DEFCATOP (scm_m, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
   SparseMatrix tmp (v2.matrix_value ());
   return octave_value
          (v1.sparse_complex_matrix_value ().concat (tmp, ra_idx));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-scm-s.cc
--- a/libinterp/operators/op-scm-s.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-scm-s.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -54,8 +54,8 @@
 DEFBINOP (div, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v1.sparse_complex_matrix_value () / v2.double_value ());
 }
@@ -63,8 +63,8 @@
 DEFBINOP (pow, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   double tmp = v2.scalar_value ();
   if (static_cast<int> (tmp) == tmp)
@@ -76,8 +76,8 @@
 DEFBINOP (ldiv, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     return octave_value (SparseComplexMatrix (1, 1, v2.scalar_value ()
@@ -105,8 +105,8 @@
 DEFBINOP (el_div, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v1.sparse_complex_matrix_value () / v2.double_value ());
 }
@@ -116,8 +116,8 @@
 DEFBINOP (el_ldiv, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value
          (elem_xdiv (v2.double_value (), v1.sparse_complex_matrix_value ()));
@@ -129,8 +129,8 @@
 DEFCATOP (scm_s, sparse_complex_matrix, 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);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
   SparseComplexMatrix tmp (1, 1, v2.complex_value ());
   return octave_value
          (v1.sparse_complex_matrix_value ().concat (tmp, ra_idx));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-scm-scm.cc
--- a/libinterp/operators/op-scm-scm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-scm-scm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -53,7 +53,7 @@
 DEFUNOP (transpose, sparse_complex_matrix)
 {
   const octave_sparse_complex_matrix& v
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a);
   return octave_value
          (v.sparse_complex_matrix_value ().transpose (),
           v.matrix_type ().transpose ());
@@ -62,7 +62,7 @@
 DEFUNOP (hermitian, sparse_complex_matrix)
 {
   const octave_sparse_complex_matrix& v
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a);
   return octave_value
          (v.sparse_complex_matrix_value ().hermitian (),
           v.matrix_type ().transpose ());
@@ -78,9 +78,9 @@
 DEFBINOP (div, sparse_complex_matrix, sparse_complex_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (v1.sparse_complex_matrix_value () / v2.complex_value ());
@@ -103,9 +103,9 @@
 DEFBINOP (ldiv, sparse_complex_matrix, sparse_complex_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     return octave_value (v2.sparse_complex_matrix_value () / v1.complex_value ());
@@ -136,9 +136,9 @@
 DEFBINOP (el_ldiv, sparse_complex_matrix, sparse_complex_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value (quotient (v2.sparse_complex_matrix_value (),
                                  v1.sparse_complex_matrix_value ()));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-scm-sm.cc
--- a/libinterp/operators/op-scm-sm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-scm-sm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -51,9 +51,9 @@
 DEFBINOP (div, sparse_complex_matrix, sparse_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (v1.sparse_complex_matrix_value () / v2.scalar_value ());
@@ -76,9 +76,9 @@
 DEFBINOP (ldiv, sparse_complex_matrix, sparse_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     return octave_value (v2.sparse_matrix_value () / v1.complex_value ());
@@ -108,9 +108,9 @@
 DEFBINOP (el_ldiv, sparse_complex_matrix, sparse_matrix)
 {
   const octave_sparse_complex_matrix& v1
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   return octave_value (quotient (v2.sparse_matrix_value (),
                                  v1.sparse_complex_matrix_value ()));
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-sm-cm.cc
--- a/libinterp/operators/op-sm-cm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-sm-cm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -53,9 +53,9 @@
 DEFBINOP (div, sparse_matrix, complex_matrix)
 {
   const octave_sparse_matrix& v1
-    = dynamic_cast<const octave_sparse_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   ComplexMatrix ret = xdiv (v1.matrix_value (),
@@ -73,9 +73,9 @@
 DEFBINOP (ldiv, sparse_matrix, complex_matrix)
 {
   const octave_sparse_matrix& v1
-    = dynamic_cast<const octave_sparse_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     return octave_value (v2.complex_array_value () / v1.scalar_value ());
@@ -104,9 +104,9 @@
 DEFBINOP (el_pow, sparse_matrix, complex_matrix)
 {
   const octave_sparse_matrix& v1
-    = dynamic_cast<const octave_sparse_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   return octave_value
          (elem_xpow (v1.sparse_matrix_value (), SparseComplexMatrix
@@ -116,9 +116,9 @@
 DEFBINOP (el_ldiv, sparse_matrix, complex_matrix)
 {
   const octave_sparse_matrix& v1
-    = dynamic_cast<const octave_sparse_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
 
   return octave_value
          (quotient (v2.complex_matrix_value (), v1.sparse_matrix_value ()));
@@ -129,9 +129,9 @@
 
 DEFCATOP (sm_cm, sparse_matrix, complex_matrix)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_complex_matrix& v2
-    = dynamic_cast<const octave_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_complex_matrix&> (a2);
   SparseComplexMatrix tmp (v2.complex_matrix_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
 }
@@ -139,7 +139,7 @@
 DEFCONV (sparse_complex_matrix_conv, sparse_matrix, sparse_complex_matrix)
 {
   const octave_sparse_matrix& v
-    = dynamic_cast<const octave_sparse_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a);
   return new octave_complex_matrix (v.complex_matrix_value ());
 }
 
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-sm-cs.cc
--- a/libinterp/operators/op-sm-cs.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-sm-cs.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -52,23 +52,23 @@
 
 DEFBINOP (div, sparse_matrix, complex)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.sparse_matrix_value () / v2.complex_value ());
 }
 
 DEFBINOP (pow, sparse_matrix, complex)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
   return xpow (v1.matrix_value (), v2.complex_value ());
 }
 
 DEFBINOP (ldiv, sparse_matrix, complex)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     return octave_value (SparseComplexMatrix (1, 1, v2.complex_value ()
@@ -95,8 +95,8 @@
 
 DEFBINOP (el_div, sparse_matrix, complex)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (v1.sparse_matrix_value () / v2.complex_value ());
 }
@@ -105,8 +105,8 @@
 
 DEFBINOP (el_ldiv, sparse_matrix, complex)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
 
   return octave_value (elem_xdiv (v2.complex_value (),
                                   v1.sparse_matrix_value ()));
@@ -117,8 +117,8 @@
 
 DEFCATOP (sm_cs, sparse_matrix, complex)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_complex& v2 = dynamic_cast<const octave_complex&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_complex& v2 = DYNORSTAT_CAST<const octave_complex&> (a2);
   SparseComplexMatrix tmp (1, 1, v2.complex_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-sm-m.cc
--- a/libinterp/operators/op-sm-m.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-sm-m.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -52,8 +52,8 @@
 
 DEFBINOP (div, sparse_matrix, matrix)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
   MatrixType typ = v2.matrix_type ();
 
   Matrix ret = xdiv (v1.matrix_value (), v2.matrix_value (), typ);
@@ -69,8 +69,8 @@
 
 DEFBINOP (ldiv, sparse_matrix, matrix)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     return octave_value (v2.array_value () / v1.scalar_value ());
@@ -100,8 +100,8 @@
 
 DEFBINOP (el_pow, sparse_matrix, matrix)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   return octave_value (elem_xpow (v1.sparse_matrix_value (),
                                   SparseMatrix (v2.matrix_value ())));
@@ -109,8 +109,8 @@
 
 DEFBINOP (el_ldiv, sparse_matrix, matrix)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   return octave_value
          (quotient (v2.matrix_value (), v1.sparse_matrix_value ()));
@@ -121,8 +121,8 @@
 
 DEFCATOP (sm_m, sparse_matrix, matrix)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
   SparseMatrix tmp (v2.matrix_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-sm-s.cc
--- a/libinterp/operators/op-sm-s.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-sm-s.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -49,16 +49,16 @@
 
 DEFBINOP (div, sparse_matrix, scalar)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v1.sparse_matrix_value () / v2.double_value ());
 }
 
 DEFBINOP (pow, sparse_matrix, scalar)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   double tmp = v2.scalar_value ();
   if (static_cast<int> (tmp) == tmp)
@@ -69,8 +69,8 @@
 
 DEFBINOP (ldiv, sparse_matrix, scalar)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     return octave_value (SparseMatrix(1, 1, v2.scalar_value () / v1.scalar_value ()));
@@ -96,8 +96,8 @@
 
 DEFBINOP (el_div, sparse_matrix, scalar)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value (v1.sparse_matrix_value () / v2.double_value ());
 }
@@ -106,8 +106,8 @@
 
 DEFBINOP (el_ldiv, sparse_matrix, scalar)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   return octave_value
          (elem_xdiv (v2.complex_value (), v1.sparse_matrix_value ()));
@@ -118,8 +118,8 @@
 
 DEFCATOP (sm_s, sparse_matrix, scalar)
 {
-  const octave_sparse_matrix& v1 = dynamic_cast<const octave_sparse_matrix&> (a1);
-  const octave_scalar& v2 = dynamic_cast<const octave_scalar&> (a2);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
   SparseMatrix tmp (1, 1, v2.scalar_value ());
   return octave_value (v1.sparse_matrix_value (). concat (tmp, ra_idx));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-sm-scm.cc
--- a/libinterp/operators/op-sm-scm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-sm-scm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -51,9 +51,9 @@
 DEFBINOP (div, sparse_matrix, sparse_complex_matrix)
 {
   const octave_sparse_matrix& v1
-    = dynamic_cast<const octave_sparse_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (v1.sparse_matrix_value () / v2.complex_value ());
@@ -76,9 +76,9 @@
 DEFBINOP (ldiv, sparse_matrix, sparse_complex_matrix)
 {
   const octave_sparse_matrix& v1
-    = dynamic_cast<const octave_sparse_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     return octave_value (v2.sparse_complex_matrix_value () / v1.scalar_value ());
@@ -109,9 +109,9 @@
 DEFBINOP (el_ldiv, sparse_matrix, sparse_complex_matrix)
 {
   const octave_sparse_matrix& v1
-    = dynamic_cast<const octave_sparse_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_sparse_complex_matrix& v2
-    = dynamic_cast<const octave_sparse_complex_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_complex_matrix&> (a2);
 
   return octave_value (quotient (v2.sparse_complex_matrix_value (),
                                  v1.sparse_matrix_value ()));
@@ -125,7 +125,7 @@
 DEFCONV (sparse_complex_matrix_conv, sparse_matrix, sparse_complex_matrix)
 {
   const octave_sparse_matrix& v
-    = dynamic_cast<const octave_sparse_matrix&> (a);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a);
   return new octave_sparse_complex_matrix (v.sparse_complex_matrix_value ());
 }
 
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-sm-sm.cc
--- a/libinterp/operators/op-sm-sm.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-sm-sm.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -48,7 +48,7 @@
 
 DEFUNOP (transpose, sparse_matrix)
 {
-  const octave_sparse_matrix& v = dynamic_cast<const octave_sparse_matrix&> (a);
+  const octave_sparse_matrix& v = DYNORSTAT_CAST<const octave_sparse_matrix&> (a);
   return octave_value (v.sparse_matrix_value ().transpose (),
                        v.matrix_type ().transpose ());
 }
@@ -63,9 +63,9 @@
 oct_binop_sub (const octave_base_value& a1, const octave_base_value& a2)
 {
   const octave_sparse_matrix& v1
-    = dynamic_cast<const octave_sparse_matrix&> (a1);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
   const octave_sparse_matrix& v2
-    = dynamic_cast<const octave_sparse_matrix&> (a2);
+    = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
   SparseMatrix m = v1.sparse_matrix_value () - v2.sparse_matrix_value ();
 
   return octave_value (m);
@@ -75,8 +75,8 @@
 
 DEFBINOP (div, sparse_matrix, 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);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   if (v2.rows () == 1 && v2.columns () == 1)
     return octave_value (v1.sparse_matrix_value () / v2.scalar_value ());
@@ -98,8 +98,8 @@
 
 DEFBINOP (ldiv, sparse_matrix, 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);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
 
   if (v1.rows () == 1 && v1.columns () == 1)
     return octave_value (v2.sparse_matrix_value () / v1.double_value ());
@@ -129,8 +129,8 @@
 
 DEFBINOP (el_ldiv, sparse_matrix, 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);
+  const octave_sparse_matrix& v1 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a1);
+  const octave_sparse_matrix& v2 = DYNORSTAT_CAST<const octave_sparse_matrix&> (a2);
   return octave_value
          (quotient (v2.sparse_matrix_value (), v1.sparse_matrix_value ()));
 }
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-str-m.cc
--- a/libinterp/operators/op-str-m.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-str-m.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -39,8 +39,8 @@
 
 DEFASSIGNOP (assign, char_matrix_str, 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_char_matrix_str& v1 = DYNORSTAT_CAST<octave_char_matrix_str&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   octave_value tmp
     = v2.convert_to_str_internal (false, false,
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-str-s.cc
--- a/libinterp/operators/op-str-s.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-str-s.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -39,8 +39,8 @@
 
 DEFASSIGNOP (assign, char_matrix_str, 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_char_matrix_str& v1 = DYNORSTAT_CAST<octave_char_matrix_str&> (a1);
+  const octave_scalar& v2 = DYNORSTAT_CAST<const octave_scalar&> (a2);
 
   octave_value tmp
     = v2.convert_to_str_internal (false, false,
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-str-str.cc
--- a/libinterp/operators/op-str-str.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-str-str.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -42,7 +42,7 @@
 DEFUNOP (transpose, char_matrix_str)
 {
   const octave_char_matrix_str& v
-    = dynamic_cast<const octave_char_matrix_str&> (a);
+    = DYNORSTAT_CAST<const octave_char_matrix_str&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -64,8 +64,8 @@
     bool a1_is_scalar = a1_dims.all_ones ();                            \
     bool a2_is_scalar = a2_dims.all_ones ();                            \
                                                                         \
-    const octave_ ## t1& v1 = dynamic_cast<const octave_ ## t1&> (a1);  \
-    const octave_ ## t2& v2 = dynamic_cast<const octave_ ## t2&> (a2);  \
+    const octave_ ## t1& v1 = DYNORSTAT_CAST<const octave_ ## t1&> (a1);  \
+    const octave_ ## t2& v2 = DYNORSTAT_CAST<const octave_ ## t2&> (a2);  \
                                                                         \
     if (a1_is_scalar)                                                   \
       {                                                                 \
@@ -102,9 +102,9 @@
 
 DEFASSIGNOP (assign, char_matrix_str, char_matrix_str)
 {
-  octave_char_matrix_str& v1 = dynamic_cast<octave_char_matrix_str&> (a1);
+  octave_char_matrix_str& v1 = DYNORSTAT_CAST<octave_char_matrix_str&> (a1);
   const octave_char_matrix_str& v2
-    = dynamic_cast<const octave_char_matrix_str&> (a2);
+    = DYNORSTAT_CAST<const octave_char_matrix_str&> (a2);
 
   v1.assign (idx, v2.char_array_value ());
   return octave_value ();
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/op-struct.cc
--- a/libinterp/operators/op-struct.cc	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/op-struct.cc	Sun Nov 21 16:49:58 2021 +0100
@@ -41,7 +41,7 @@
 
 DEFUNOP (transpose, struct)
 {
-  const octave_struct& v = dynamic_cast<const octave_struct&> (a);
+  const octave_struct& v = DYNORSTAT_CAST<const octave_struct&> (a);
 
   if (v.ndims () > 2)
     error ("transpose not defined for N-D objects");
@@ -51,7 +51,7 @@
 
 DEFUNOP (scalar_transpose, scalar_struct)
 {
-  const octave_scalar_struct& v = dynamic_cast<const octave_scalar_struct&> (a);
+  const octave_scalar_struct& v = DYNORSTAT_CAST<const octave_scalar_struct&> (a);
 
   return octave_value (v.scalar_map_value ());
 }
@@ -66,8 +66,8 @@
                          const octave_base_value& a2,
                          const Array<octave_idx_type>&)
 {
-  const octave_struct& v1 = dynamic_cast<const octave_struct&> (a1);
-  const octave_matrix& v2 = dynamic_cast<const octave_matrix&> (a2);
+  const octave_struct& v1 = DYNORSTAT_CAST<const octave_struct&> (a1);
+  const octave_matrix& v2 = DYNORSTAT_CAST<const octave_matrix&> (a2);
 
   NDArray tmp = v2.array_value ();
   dim_vector dv = tmp.dims ();
@@ -83,8 +83,8 @@
                          const octave_base_value& a2,
                          const Array<octave_idx_type>&)
 {
-  const octave_matrix& v1 = dynamic_cast<const octave_matrix&> (a1);
-  const octave_struct& v2 = dynamic_cast<const octave_struct&> (a2);
+  const octave_matrix& v1 = DYNORSTAT_CAST<const octave_matrix&> (a1);
+  const octave_struct& v2 = DYNORSTAT_CAST<const octave_struct&> (a2);
 
   NDArray tmp = v1.array_value ();
   dim_vector dv = tmp.dims ();
diff -r 1a3cd0f2e096 -r fa58b36eaffe libinterp/operators/ops.h
--- a/libinterp/operators/ops.h	Wed Dec 22 23:22:07 2021 +0100
+++ b/libinterp/operators/ops.h	Sun Nov 21 16:49:58 2021 +0100
@@ -35,6 +35,15 @@
   class type_info;
 }
 
+// Use the static_cast rather than dynamic_cast when
+// internal checks are not enabled to speed up execution,
+// avoiding RTTI calls.
+#ifdef OCTAVE_ENABLE_INTERNAL_CHECKS
+#define DYNORSTAT_CAST dynamic_cast
+#else
+#define DYNORSTAT_CAST static_cast
+#endif
+
 // Concatenation macros that enforce argument prescan
 #define CONCAT2X(x, y) x ## y
 #define CONCAT2(x, y) CONCAT2X (x, y)
@@ -88,8 +97,8 @@
                                  const octave_value_list& idx,          \
                                  const octave_base_value& a2)           \
   {                                                                     \
-    CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     v1.f (idx, v2.CONCAT2 (t1, _value) ());                             \
     return octave_value ();                                             \
@@ -101,7 +110,7 @@
                                  const octave_value_list& idx,          \
                                  const octave_base_value&)              \
   {                                                                     \
-    CONCAT2 (octave_, t)& v = dynamic_cast<CONCAT2 (octave_, t)&> (a);  \
+    CONCAT2 (octave_, t)& v = DYNORSTAT_CAST<CONCAT2 (octave_, t)&> (a);  \
                                                                         \
     v.f (idx);                                                          \
     return octave_value ();                                             \
@@ -113,8 +122,8 @@
                                  const octave_value_list& idx,          \
                                  const octave_base_value& a2)           \
   {                                                                     \
-    CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     v1.f (idx, v2.CONCAT2 (e, _value) ());                              \
     return octave_value ();                                             \
@@ -127,8 +136,8 @@
                                  const octave_value_list& idx,          \
                                  const octave_base_value& a2)           \
   {                                                                     \
-    CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     assert (idx.empty ());                                              \
     v1.matrix_ref () op v2.CONCAT2 (f, _value) ();                      \
@@ -142,8 +151,8 @@
                                  const octave_value_list& idx,          \
                                  const octave_base_value& a2)           \
   {                                                                     \
-    CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     assert (idx.empty ());                                              \
     fnop (v1.matrix_ref (), v2.CONCAT2 (f, _value) ());                 \
@@ -157,7 +166,7 @@
                                  const octave_value_list& idx,          \
                                  const octave_value& a2)                \
   {                                                                     \
-    CONCAT2 (octave_, t1)& v1 = dynamic_cast<CONCAT2 (octave_, t1)&> (a1); \
+    CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<CONCAT2 (octave_, t1)&> (a1); \
                                                                         \
     v1.f (idx, a2);                                                     \
     return octave_value ();                                             \
@@ -182,7 +191,7 @@
   static octave_value                                                   \
   CONCAT2 (oct_unop_, name) (const octave_base_value& a)                \
   {                                                                     \
-    const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
+    const CONCAT2 (octave_, t)& v = DYNORSTAT_CAST<const CONCAT2 (octave_, t)&> (a); \
     return octave_value (op v.CONCAT2 (t, _value) ());                  \
   }
 
@@ -190,7 +199,7 @@
   static octave_value                                                   \
   CONCAT2 (oct_unop_, name) (const octave_base_value& a)                \
   {                                                                     \
-    const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
+    const CONCAT2 (octave_, t)& v = DYNORSTAT_CAST<const CONCAT2 (octave_, t)&> (a); \
     return octave_value (op v.CONCAT2 (e, _value) ());                  \
   }
 
@@ -200,7 +209,7 @@
   static octave_value                                                   \
   CONCAT2 (oct_unop_, name) (const octave_base_value& a)                \
   {                                                                     \
-    const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
+    const CONCAT2 (octave_, t)& v = DYNORSTAT_CAST<const CONCAT2 (octave_, t)&> (a); \
     return octave_value (f (v.CONCAT2 (t, _value) ()));                 \
   }
 
@@ -208,7 +217,7 @@
   static octave_value                                                   \
   CONCAT2 (oct_unop_, name) (const octave_base_value& a)                \
   {                                                                     \
-    const CONCAT2 (octave_, t)& v = dynamic_cast<const CONCAT2 (octave_, t)&> (a); \
+    const CONCAT2 (octave_, t)& v = DYNORSTAT_CAST<const CONCAT2 (octave_, t)&> (a); \
     return octave_value (f (v.CONCAT2 (e, _value) ()));                 \
   }
 
@@ -216,7 +225,7 @@
   static void                                                           \
   CONCAT2 (oct_unop_, name) (octave_base_value& a)                      \
   {                                                                     \
-    CONCAT2 (octave_, t)& v = dynamic_cast<CONCAT2 (octave_, t)&> (a);  \
+    CONCAT2 (octave_, t)& v = DYNORSTAT_CAST<CONCAT2 (octave_, t)&> (a);  \
     v.method ();                                                        \
   }
 
@@ -235,8 +244,8 @@
   CONCAT2 (oct_binop_, name) (const octave_base_value& a1,              \
                               const octave_base_value& a2)              \
   {                                                                     \
-    const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    const CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<const CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     return octave_value                                                 \
       (v1.CONCAT2 (t1, _value) () op v2.CONCAT2 (t2, _value) ());       \
@@ -247,8 +256,8 @@
   CONCAT2 (oct_binop_, name) (const octave_base_value& a1,              \
                               const octave_base_value& a2)              \
   {                                                                     \
-    const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    const CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<const CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     warn_complex_cmp ();                                                \
                                                                         \
@@ -261,8 +270,8 @@
   CONCAT2 (oct_binop_, name) (const octave_base_value& a1,              \
                               const octave_base_value& a2)              \
   {                                                                     \
-    const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    const CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<const CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     if (octave::math::isnan (v1.CONCAT2 (t1, _value) ()) || octave::math::isnan (v2.CONCAT2 (t2, _value) ())) \
       octave::err_nan_to_logical_conversion ();                                 \
@@ -276,8 +285,8 @@
   CONCAT2 (oct_binop_, name) (const octave_base_value& a1,              \
                               const octave_base_value& a2)              \
   {                                                                     \
-    const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    const CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<const CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     return octave_value                                                 \
       (v1.CONCAT2 (e1, _value) () op v2.CONCAT2 (e2, _value) ());       \
@@ -290,8 +299,8 @@
   CONCAT2 (oct_binop_, name) (const octave_base_value& a1,              \
                               const octave_base_value& a2)              \
   {                                                                     \
-    const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    const CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<const CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     return octave_value (f (v1.CONCAT2 (t1, _value) (), v2.CONCAT2 (t2, _value) ())); \
   }
@@ -301,8 +310,8 @@
   CONCAT2 (oct_binop_, name) (const octave_base_value& a1,              \
                               const octave_base_value& a2)              \
   {                                                                     \
-    const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    const CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<const CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     return octave_value (f (v1.CONCAT2 (e1, _value) (), v2.CONCAT2 (e2, _value) ())); \
   }
@@ -312,8 +321,8 @@
   CONCAT2 (oct_binop_, name) (const octave_base_value& a1,              \
                               const octave_base_value& a2)              \
   {                                                                     \
-    const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    const CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<const CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     return octave_value (f (v1.CONCAT2 (e1, _value) (), v2.CONCAT2 (e2, _value) ())); \
   }
@@ -338,8 +347,8 @@
                               const octave_base_value& a2,              \
                               const Array<octave_idx_type>& ra_idx)     \
   {                                                                     \
-    const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    const CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<const CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     return octave_value (v1.CONCAT2 (t1, _value) () . f (v2.CONCAT2 (t2, _value) (), ra_idx)); \
   }
@@ -350,8 +359,8 @@
                               const octave_base_value& a2,              \
                               const Array<octave_idx_type>& ra_idx)     \
   {                                                                     \
-    const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    const CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<const CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     return octave_value (v1.CONCAT2 (e1, _value) () . f (v2.CONCAT2 (e2, _value) (), ra_idx)); \
   }
@@ -362,8 +371,8 @@
                               const octave_base_value& a2,              \
                               const Array<octave_idx_type>& ra_idx)     \
   {                                                                     \
-    const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    const CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<const CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_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 ())    \
@@ -379,8 +388,8 @@
                               const octave_base_value& a2,              \
                               const Array<octave_idx_type>& ra_idx)     \
   {                                                                     \
-    const CONCAT2 (octave_, t1)& v1 = dynamic_cast<const CONCAT2 (octave_, t1)&> (a1); \
-    const CONCAT2 (octave_, t2)& v2 = dynamic_cast<const CONCAT2 (octave_, t2)&> (a2); \
+    const CONCAT2 (octave_, t1)& v1 = DYNORSTAT_CAST<const CONCAT2 (octave_, t1)&> (a1); \
+    const CONCAT2 (octave_, t2)& v2 = DYNORSTAT_CAST<const CONCAT2 (octave_, t2)&> (a2); \
                                                                         \
     return octave_value (tc1 (v1.CONCAT2 (e1, _value) ()) . f (tc2 (v2.CONCAT2 (e2, _value) ()), ra_idx)); \
   }
