changeset 10362:b47ab50a6aa8

simplify appliers in mx-inlines.cc
author Jaroslav Hajek <highegg@gmail.com>
date Fri, 26 Feb 2010 09:47:54 +0100
parents b4f67ca318d8
children a0728e81ed25
files liboctave/CMatrix.cc liboctave/CNDArray.cc liboctave/ChangeLog liboctave/DiagArray2.h liboctave/MArray-decl.h liboctave/MArray.cc liboctave/MDiagArray2.cc liboctave/MDiagArray2.h liboctave/boolMatrix.cc liboctave/boolNDArray.cc liboctave/bsxfun-defs.cc liboctave/chMatrix.cc liboctave/chNDArray.cc liboctave/dMatrix.cc liboctave/dNDArray.cc liboctave/fCMatrix.cc liboctave/fCNDArray.cc liboctave/fMatrix.cc liboctave/fNDArray.cc liboctave/intNDArray.cc liboctave/mx-inlines.cc liboctave/mx-op-defs.h
diffstat 22 files changed, 356 insertions(+), 357 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/CMatrix.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/CMatrix.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -3069,7 +3069,7 @@
 boolMatrix
 ComplexMatrix::operator ! (void) const
 {
-  return do_mx_unary_op<boolMatrix, ComplexMatrix> (*this, mx_inline_not);
+  return do_mx_unary_op<bool, Complex> (*this, mx_inline_not);
 }
 
 // other operations
@@ -3202,43 +3202,43 @@
 boolMatrix
 ComplexMatrix::all (int dim) const
 {
-  return do_mx_red_op<boolMatrix, Complex> (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, Complex> (*this, dim, mx_inline_all);
 }
 
 boolMatrix
 ComplexMatrix::any (int dim) const
 {
-  return do_mx_red_op<boolMatrix, Complex> (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, Complex> (*this, dim, mx_inline_any);
 }
 
 ComplexMatrix
 ComplexMatrix::cumprod (int dim) const
 {
-  return do_mx_cum_op<ComplexMatrix, Complex> (*this, dim, mx_inline_cumprod);
+  return do_mx_cum_op<Complex, Complex> (*this, dim, mx_inline_cumprod);
 }
 
 ComplexMatrix
 ComplexMatrix::cumsum (int dim) const
 {
-  return do_mx_cum_op<ComplexMatrix, Complex> (*this, dim, mx_inline_cumsum);
+  return do_mx_cum_op<Complex, Complex> (*this, dim, mx_inline_cumsum);
 }
 
 ComplexMatrix
 ComplexMatrix::prod (int dim) const
 {
-  return do_mx_red_op<ComplexMatrix, Complex> (*this, dim, mx_inline_prod);
+  return do_mx_red_op<Complex, Complex> (*this, dim, mx_inline_prod);
 }
 
 ComplexMatrix
 ComplexMatrix::sum (int dim) const
 {
-  return do_mx_red_op<ComplexMatrix, Complex> (*this, dim, mx_inline_sum);
+  return do_mx_red_op<Complex, Complex> (*this, dim, mx_inline_sum);
 }
 
 ComplexMatrix
 ComplexMatrix::sumsq (int dim) const
 {
-  return do_mx_red_op<Matrix, Complex> (*this, dim, mx_inline_sumsq);
+  return do_mx_red_op<double, Complex> (*this, dim, mx_inline_sumsq);
 }
 
 Matrix ComplexMatrix::abs (void) const
--- a/liboctave/CNDArray.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/CNDArray.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -500,7 +500,7 @@
 boolNDArray
 ComplexNDArray::operator ! (void) const
 {
-  return do_mx_unary_op<boolNDArray, ComplexNDArray> (*this, mx_inline_not);
+  return do_mx_unary_op<bool, Complex> (*this, mx_inline_not);
 }
 
 // FIXME -- this is not quite the right thing.
@@ -620,55 +620,55 @@
 boolNDArray
 ComplexNDArray::all (int dim) const
 {
-  return do_mx_red_op<boolNDArray, Complex> (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, Complex> (*this, dim, mx_inline_all);
 }
 
 boolNDArray
 ComplexNDArray::any (int dim) const
 {
-  return do_mx_red_op<boolNDArray, Complex> (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, Complex> (*this, dim, mx_inline_any);
 }
 
 ComplexNDArray
 ComplexNDArray::cumprod (int dim) const
 {
-  return do_mx_cum_op<ComplexNDArray, Complex> (*this, dim, mx_inline_cumprod);
+  return do_mx_cum_op<Complex, Complex> (*this, dim, mx_inline_cumprod);
 }
 
 ComplexNDArray
 ComplexNDArray::cumsum (int dim) const
 {
-  return do_mx_cum_op<ComplexNDArray, Complex> (*this, dim, mx_inline_cumsum);
+  return do_mx_cum_op<Complex, Complex> (*this, dim, mx_inline_cumsum);
 }
 
 ComplexNDArray
 ComplexNDArray::prod (int dim) const
 {
-  return do_mx_red_op<ComplexNDArray, Complex> (*this, dim, mx_inline_prod);
+  return do_mx_red_op<Complex, Complex> (*this, dim, mx_inline_prod);
 }
 
 ComplexNDArray
 ComplexNDArray::sum (int dim) const
 {
-  return do_mx_red_op<ComplexNDArray, Complex> (*this, dim, mx_inline_sum);
+  return do_mx_red_op<Complex, Complex> (*this, dim, mx_inline_sum);
 }
 
 ComplexNDArray
 ComplexNDArray::xsum (int dim) const
 {
-  return do_mx_red_op<ComplexNDArray, Complex> (*this, dim, mx_inline_xsum);
+  return do_mx_red_op<Complex, Complex> (*this, dim, mx_inline_xsum);
 }
 
 ComplexNDArray
 ComplexNDArray::sumsq (int dim) const
 {
-  return do_mx_red_op<NDArray, Complex> (*this, dim, mx_inline_sumsq);
+  return do_mx_red_op<double, Complex> (*this, dim, mx_inline_sumsq);
 }
 
 ComplexNDArray
 ComplexNDArray::diff (octave_idx_type order, int dim) const
 {
-  return do_mx_diff_op<ComplexNDArray> (*this, dim, order, mx_inline_diff);
+  return do_mx_diff_op<Complex> (*this, dim, order, mx_inline_diff);
 }
 
 ComplexNDArray
@@ -702,79 +702,79 @@
 ComplexNDArray
 ComplexNDArray::max (int dim) const
 {
-  return do_mx_minmax_op<ComplexNDArray> (*this, dim, mx_inline_max);
+  return do_mx_minmax_op<Complex> (*this, dim, mx_inline_max);
 }
 
 ComplexNDArray
 ComplexNDArray::max (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_minmax_op<ComplexNDArray> (*this, idx_arg, dim, mx_inline_max);
+  return do_mx_minmax_op<Complex> (*this, idx_arg, dim, mx_inline_max);
 }
 
 ComplexNDArray
 ComplexNDArray::min (int dim) const
 {
-  return do_mx_minmax_op<ComplexNDArray> (*this, dim, mx_inline_min);
+  return do_mx_minmax_op<Complex> (*this, dim, mx_inline_min);
 }
 
 ComplexNDArray
 ComplexNDArray::min (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_minmax_op<ComplexNDArray> (*this, idx_arg, dim, mx_inline_min);
+  return do_mx_minmax_op<Complex> (*this, idx_arg, dim, mx_inline_min);
 }
 
 ComplexNDArray
 ComplexNDArray::cummax (int dim) const
 {
-  return do_mx_cumminmax_op<ComplexNDArray> (*this, dim, mx_inline_cummax);
+  return do_mx_cumminmax_op<Complex> (*this, dim, mx_inline_cummax);
 }
 
 ComplexNDArray
 ComplexNDArray::cummax (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_cumminmax_op<ComplexNDArray> (*this, idx_arg, dim, mx_inline_cummax);
+  return do_mx_cumminmax_op<Complex> (*this, idx_arg, dim, mx_inline_cummax);
 }
 
 ComplexNDArray
 ComplexNDArray::cummin (int dim) const
 {
-  return do_mx_cumminmax_op<ComplexNDArray> (*this, dim, mx_inline_cummin);
+  return do_mx_cumminmax_op<Complex> (*this, dim, mx_inline_cummin);
 }
 
 ComplexNDArray
 ComplexNDArray::cummin (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_cumminmax_op<ComplexNDArray> (*this, idx_arg, dim, mx_inline_cummin);
+  return do_mx_cumminmax_op<Complex> (*this, idx_arg, dim, mx_inline_cummin);
 }
 
 NDArray
 ComplexNDArray::abs (void) const
 {
-  return do_mx_unary_map<NDArray, ComplexNDArray, std::abs> (*this);
+  return do_mx_unary_map<double, Complex, std::abs> (*this);
 }
 
 boolNDArray
 ComplexNDArray::isnan (void) const
 {
-  return do_mx_unary_map<boolNDArray, ComplexNDArray, xisnan> (*this);
+  return do_mx_unary_map<bool, Complex, xisnan> (*this);
 }
 
 boolNDArray
 ComplexNDArray::isinf (void) const
 {
-  return do_mx_unary_map<boolNDArray, ComplexNDArray, xisinf> (*this);
+  return do_mx_unary_map<bool, Complex, xisinf> (*this);
 }
 
 boolNDArray
 ComplexNDArray::isfinite (void) const
 {
-  return do_mx_unary_map<boolNDArray, ComplexNDArray, xfinite> (*this);
+  return do_mx_unary_map<bool, Complex, xfinite> (*this);
 }
 
 ComplexNDArray
 conj (const ComplexNDArray& a)
 {
-  return do_mx_unary_map<ComplexNDArray, ComplexNDArray, std::conj> (a);
+  return do_mx_unary_map<Complex, Complex, std::conj> (a);
 }
 
 ComplexNDArray&
@@ -930,7 +930,7 @@
   if (a.is_shared ())
     a = a * s;
   else
-    do_ms_inplace_op<ComplexNDArray, double> (a, s, mx_inline_mul2);
+    do_ms_inplace_op<Complex, double> (a, s, mx_inline_mul2);
   return a;
 }
 
@@ -939,7 +939,7 @@
   if (a.is_shared ())
     return a = a / s;
   else
-    do_ms_inplace_op<ComplexNDArray, double> (a, s, mx_inline_div2);
+    do_ms_inplace_op<Complex, double> (a, s, mx_inline_div2);
   return a;
 }
 
--- a/liboctave/ChangeLog	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/ChangeLog	Fri Feb 26 09:47:54 2010 +0100
@@ -1,3 +1,30 @@
+2010-02-26  Jaroslav Hajek  <highegg@gmail.com>
+
+	* mx-inlines.cc: Parameterize all appliers by value types rather than
+	Array types. Return & accept Array instances.
+	* mx-op-defs.h: Update references.
+	* CMatrix.cc: Ditto.
+	* CNDArray.cc: Ditto.
+	* DiagArray2.h: Ditto.
+	* MArray.cc: Ditto.
+	* boolMatrix.cc: Ditto.
+	* boolNDArray.cc: Ditto.
+	* bsxfun-defs.cc: Ditto.
+	* chMatrix.cc: Ditto.
+	* chNDArray.cc: Ditto.
+	* dMatrix.cc: Ditto.
+	* dNDArray.cc: Ditto.
+	* fCMatrix.cc: Ditto.
+	* fCNDArray.cc: Ditto.
+	* fMatrix.cc: Ditto.
+	* fNDArray.cc: Ditto.
+	* intNDArray.cc: Ditto.
+	* MDiagArray2.cc: Remove computed assignment operators, adapt 
+	operators to new mechanism.
+	* MDiagArray2.h: Declare operators as friends.
+	* MArray-decl.h (MDIAGARRAY2_OPS_FRIEND_DECLS): Don't expand
+	MARRAY_OP_ASSIGN_FRIENDS here.
+
 2010-02-25  John W. Eaton  <jwe@octave.org>
 
 	* eigs-base.cc: Use octave_idx_type for Fortran LOGICAL values
--- a/liboctave/DiagArray2.h	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/DiagArray2.h	Fri Feb 26 09:47:54 2010 +0100
@@ -114,6 +114,9 @@
   DiagArray2 (const Array<T>& a) 
     : Array<T> (a.as_column ()), d1 (a.numel ()), d2 (a.numel ()) { }
 
+  DiagArray2 (const Array<T>& a, octave_idx_type r, octave_idx_type c) 
+    : Array<T> (a.as_column ()), d1 (r), d2 (c) { }
+
   DiagArray2 (const DiagArray2<T>& a) 
     : Array<T> (a), d1 (a.d1), d2 (a.d2) { }
 
--- a/liboctave/MArray-decl.h	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/MArray-decl.h	Fri Feb 26 09:47:54 2010 +0100
@@ -228,7 +228,6 @@
   MARRAY_BINOP_FRIENDS (A_T, API)
 
 #define MDIAGARRAY2_OPS_FRIEND_DECLS(A_T, API) \
-  MARRAY_OP_ASSIGN_FRIENDS (A_T, A_T<T>, API) \
   MARRAY_UNOP_FRIENDS (A_T, API) \
   MDIAGARRAY2_BINOP_FRIENDS (A_T, API)
 
--- a/liboctave/MArray.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/MArray.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -143,7 +143,7 @@
   if (Array<T>::is_shared ())
     *this = - *this;
   else
-    do_mx_inplace_op<MArray<T> > (*this, mx_inline_uminus2);
+    do_mx_inplace_op<T> (*this, mx_inline_uminus2);
 }
 
 // Element by element MArray by scalar ops.
@@ -155,7 +155,7 @@
   if (a.is_shared ())
     a = a + s;
   else
-    do_ms_inplace_op<MArray<T>, T> (a, s, mx_inline_add2);
+    do_ms_inplace_op<T, T> (a, s, mx_inline_add2);
   return a;
 }
 
@@ -166,7 +166,7 @@
   if (a.is_shared ())
     a = a - s;
   else
-    do_ms_inplace_op<MArray<T>, T> (a, s, mx_inline_sub2);
+    do_ms_inplace_op<T, T> (a, s, mx_inline_sub2);
   return a;
 }
 
@@ -177,7 +177,7 @@
   if (a.is_shared ())
     a = a * s;
   else
-    do_ms_inplace_op<MArray<T>, T> (a, s, mx_inline_mul2);
+    do_ms_inplace_op<T, T> (a, s, mx_inline_mul2);
   return a;
 }
 
@@ -188,7 +188,7 @@
   if (a.is_shared ())
     a = a / s;
   else
-    do_ms_inplace_op<MArray<T>, T> (a, s, mx_inline_div2);
+    do_ms_inplace_op<T, T> (a, s, mx_inline_div2);
   return a;
 }
 
@@ -201,7 +201,7 @@
   if (a.is_shared ())
     a = a + b;
   else
-    do_mm_inplace_op<MArray<T>, MArray<T> > (a, b, mx_inline_add2, "+=");
+    do_mm_inplace_op<T, T> (a, b, mx_inline_add2, "+=");
   return a;
 }
 
@@ -212,7 +212,7 @@
   if (a.is_shared ())
     a = a - b;
   else
-    do_mm_inplace_op<MArray<T>, MArray<T> > (a, b, mx_inline_sub2, "-=");
+    do_mm_inplace_op<T, T> (a, b, mx_inline_sub2, "-=");
   return a;
 }
 
@@ -224,7 +224,7 @@
   if (a.is_shared ())
     return a = product (a, b);
   else
-    do_mm_inplace_op<MArray<T>, MArray<T> > (a, b, mx_inline_mul2, ".*=");
+    do_mm_inplace_op<T, T> (a, b, mx_inline_mul2, ".*=");
   return a;
 }
 
@@ -235,7 +235,7 @@
   if (a.is_shared ())
     return a = quotient (a, b);
   else
-    do_mm_inplace_op<MArray<T>, MArray<T> > (a, b, mx_inline_div2, "./=");
+    do_mm_inplace_op<T, T> (a, b, mx_inline_div2, "./=");
   return a;
 }
 
@@ -246,7 +246,7 @@
   MArray<T> \
   operator OP (const MArray<T>& a, const T& s) \
   { \
-    return do_ms_binary_op<MArray<T>, MArray<T>, T> (a, s, FN); \
+    return do_ms_binary_op<T, T, T> (a, s, FN); \
   }
 
 MARRAY_NDS_OP (+, mx_inline_add)
@@ -261,7 +261,7 @@
   MArray<T> \
   operator OP (const T& s, const MArray<T>& a) \
   { \
-    return do_sm_binary_op<MArray<T>, T, MArray<T> > (s, a, FN); \
+    return do_sm_binary_op<T, T, T> (s, a, FN); \
   }
 
 MARRAY_SND_OP (+, mx_inline_add)
@@ -276,7 +276,7 @@
   MArray<T> \
   FCN (const MArray<T>& a, const MArray<T>& b) \
   { \
-    return do_mm_binary_op<MArray<T>, MArray<T>, MArray<T> > (a, b, FN, #FCN); \
+    return do_mm_binary_op<T, T, T> (a, b, FN, #FCN); \
   }
 
 MARRAY_NDND_OP (operator +, +, mx_inline_add)
@@ -295,5 +295,5 @@
 MArray<T>
 operator - (const MArray<T>& a)
 {
-  return do_mx_unary_op<MArray<T>, MArray<T> > (a, mx_inline_uminus); 
+  return do_mx_unary_op<T, T> (a, mx_inline_uminus); 
 }
--- a/liboctave/MDiagArray2.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/MDiagArray2.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -51,29 +51,6 @@
 
 // Element by element MDiagArray2 by MDiagArray2 ops.
 
-template <class T>
-MDiagArray2<T>&
-operator += (MDiagArray2<T>& a, const MDiagArray2<T>& b)
-{
-  if (a.is_shared ())
-    a = a + b;
-  else
-    do_mm_inplace_op<MDiagArray2<T>, MDiagArray2<T> > (a, b, mx_inline_add2, "+=");
-  return a;
-}
-
-template <class T>
-MDiagArray2<T>&
-operator -= (MDiagArray2<T>& a, const MDiagArray2<T>& b)
-{
-  if (a.is_shared ())
-    a = a - b;
-  else
-    do_mm_inplace_op<MDiagArray2<T>, MDiagArray2<T> > (a, b, mx_inline_sub2, "-=");
-  return a;
-}
-
-
 // Element by element MDiagArray2 by scalar ops.
 
 #define MARRAY_DAS_OP(OP, FN) \
@@ -81,7 +58,7 @@
   MDiagArray2<T> \
   operator OP (const MDiagArray2<T>& a, const T& s) \
   { \
-    return do_ms_binary_op<MDiagArray2<T>, MDiagArray2<T>, T> (a, s, FN); \
+    return MDiagArray2<T> (do_ms_binary_op<T, T, T> (a, s, FN), a.d1, a.d2); \
   }
 
 MARRAY_DAS_OP (*, mx_inline_mul)
@@ -93,7 +70,7 @@
 MDiagArray2<T>
 operator * (const T& s, const MDiagArray2<T>& a)
 {
-  return do_sm_binary_op<MDiagArray2<T>, T, MDiagArray2<T> > (s, a, mx_inline_mul);
+  return MDiagArray2<T> (do_sm_binary_op<T, T, T> (s, a, mx_inline_mul), a.d1, a.d2);
 }
 
 // Element by element MDiagArray2 by MDiagArray2 ops.
@@ -103,7 +80,9 @@
   MDiagArray2<T> \
   FCN (const MDiagArray2<T>& a, const MDiagArray2<T>& b) \
   { \
-    return do_mm_binary_op<MDiagArray2<T>, MDiagArray2<T>, MDiagArray2<T> > (a, b, FN, #FCN); \
+    if (a.d1 != b.d1 || a.d2 != b.d2) \
+      gripe_nonconformant (#FCN, a.d1, a.d2, b.d1, b.d2); \
+    return MDiagArray2<T> (do_mm_binary_op<T, T, T> (a, b, FN, #FCN), a.d1, a.d2); \
   }
 
 MARRAY_DADA_OP (operator +, +, mx_inline_add)
@@ -123,5 +102,5 @@
 MDiagArray2<T>
 operator - (const MDiagArray2<T>& a)
 {
-  return do_mx_unary_op<MDiagArray2<T>, MDiagArray2<T> > (a, mx_inline_uminus); 
+  return MDiagArray2<T> (do_mx_unary_op<T, T> (a, mx_inline_uminus), a.d1, a.d2); 
 }
--- a/liboctave/MDiagArray2.h	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/MDiagArray2.h	Fri Feb 26 09:47:54 2010 +0100
@@ -63,6 +63,9 @@
 
   explicit MDiagArray2 (const Array<T>& a) : DiagArray2<T> (a) { }
 
+  MDiagArray2 (const Array<T>& a, octave_idx_type r, octave_idx_type c) 
+    : DiagArray2<T> (a, r, c) { }
+
   ~MDiagArray2 (void) { }
 
   MDiagArray2<T>& operator = (const MDiagArray2<T>& a)
@@ -104,7 +107,7 @@
   // Currently, the OPS functions don't need to be friends, but that
   // may change.
 
-  // MDIAGARRAY2_OPS_FRIEND_DECLS (MDiagArray2)
+  MDIAGARRAY2_OPS_FRIEND_DECLS (MDiagArray2, )
 
 };
 
--- a/liboctave/boolMatrix.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/boolMatrix.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -91,13 +91,13 @@
 boolMatrix
 boolMatrix::all (int dim) const
 {
-  return do_mx_red_op<boolMatrix, bool> (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, bool> (*this, dim, mx_inline_all);
 }
 
 boolMatrix
 boolMatrix::any (int dim) const
 {
-  return do_mx_red_op<boolMatrix, bool> (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, bool> (*this, dim, mx_inline_any);
 }
 
 MM_BOOL_OPS (boolMatrix, boolMatrix)
--- a/liboctave/boolNDArray.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/boolNDArray.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -41,7 +41,7 @@
 boolNDArray
 boolNDArray::operator ! (void) const
 {
-  return do_mx_unary_op<boolNDArray> (*this, mx_inline_not);
+  return do_mx_unary_op<bool> (*this, mx_inline_not);
 }
 
 boolNDArray&
@@ -50,7 +50,7 @@
   if (is_shared ())
     *this = ! *this;
   else
-    do_mx_inplace_op<boolNDArray> (*this, mx_inline_not2);
+    do_mx_inplace_op<bool> (*this, mx_inline_not2);
 
   return *this;
 }
@@ -60,13 +60,13 @@
 boolNDArray
 boolNDArray::all (int dim) const
 {
-  return do_mx_red_op<boolNDArray, bool> (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, bool> (*this, dim, mx_inline_all);
 }
 
 boolNDArray
 boolNDArray::any (int dim) const
 {
-  return do_mx_red_op<boolNDArray, bool> (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, bool> (*this, dim, mx_inline_any);
 }
 
 NDArray 
@@ -74,14 +74,14 @@
 {
   // NOTE: going via octave_idx_type is typically faster even though it
   // requires a conversion. 
-  return do_mx_red_op<Array<octave_idx_type> , bool> (*this, dim, mx_inline_count);
+  return do_mx_red_op<octave_idx_type, bool> (*this, dim, mx_inline_count);
 }
 
 NDArray 
 boolNDArray::cumsum (int dim) const
 {
   // In this case, it's better to sum directly to doubles.
-  return do_mx_cum_op<NDArray , bool> (*this, dim, mx_inline_cumcount);
+  return do_mx_cum_op<double , bool> (*this, dim, mx_inline_cumcount);
 }
 
 boolNDArray
@@ -150,7 +150,7 @@
   if (a.is_shared ())
     a = mx_el_and (a, b);
   else
-    do_mm_inplace_op<boolNDArray, boolNDArray> (a, b, mx_inline_and2, "operator &=");
+    do_mm_inplace_op<bool, bool> (a, b, mx_inline_and2, "operator &=");
 
   return a;
 }
@@ -161,7 +161,7 @@
   if (a.is_shared ())
     a = mx_el_or (a, b);
   else
-    do_mm_inplace_op<boolNDArray, boolNDArray> (a, b, mx_inline_or2, "operator |=");
+    do_mm_inplace_op<bool, bool> (a, b, mx_inline_or2, "operator |=");
 
   return a;
 }
--- a/liboctave/bsxfun-defs.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/bsxfun-defs.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -33,18 +33,12 @@
 
 #include "mx-inlines.cc"
 
-template <class RNDA, class XNDA, class YNDA>
-RNDA
-do_bsxfun_op (const XNDA& x, const YNDA& y,
-              void (*op_vv) (size_t, typename RNDA::element_type *,
-                             const typename XNDA::element_type *,
-                             const typename YNDA::element_type *),
-              void (*op_sv) (size_t, typename RNDA::element_type *,
-                             typename XNDA::element_type,
-                             const typename YNDA::element_type *),
-              void (*op_vs) (size_t, typename RNDA::element_type *,
-                             const typename XNDA::element_type *,
-                             typename YNDA::element_type))
+template <class R, class X, class Y>
+Array<R>
+do_bsxfun_op (const Array<X>& x, const Array<Y>& y,
+              void (*op_vv) (size_t, R *, const X *, const Y *),
+              void (*op_sv) (size_t, R *, X, const Y *),
+              void (*op_vs) (size_t, R *, const X *, Y))
 {
   int nd = std::max (x.ndims (), y.ndims ());
   dim_vector dvx = x.dims ().redim (nd), dvy = y.dims ().redim (nd);
@@ -68,11 +62,11 @@
         }
     }
 
-  RNDA retval (dvr);
+  Array<R> retval (dvr);
 
-  const typename XNDA::element_type *xvec = x.fortran_vec ();
-  const typename YNDA::element_type *yvec = y.fortran_vec ();
-  typename RNDA::element_type *rvec = retval.fortran_vec ();
+  const X *xvec = x.fortran_vec ();
+  const Y *yvec = y.fortran_vec ();
+  R *rvec = retval.fortran_vec ();
 
   // Fold the common leading dimensions.
   int start;
@@ -151,15 +145,18 @@
 
 #define BSXFUN_OP_DEF_MXLOOP(OP, ARRAY, LOOP) \
   BSXFUN_OP_DEF(OP, ARRAY) \
-  { return do_bsxfun_op<ARRAY, ARRAY, ARRAY> (x, y, LOOP, LOOP, LOOP); }
+  { return do_bsxfun_op<ARRAY::element_type, ARRAY::element_type, ARRAY::element_type> \
+    (x, y, LOOP, LOOP, LOOP); }
 
 #define BSXFUN_OP2_DEF_MXLOOP(OP, ARRAY, ARRAY1, ARRAY2, LOOP) \
   BSXFUN_OP2_DEF(OP, ARRAY, ARRAY1, ARRAY2) \
-  { return do_bsxfun_op<ARRAY, ARRAY1, ARRAY2> (x, y, LOOP, LOOP, LOOP); }
+  { return do_bsxfun_op<ARRAY::element_type, ARRAY1::element_type, ARRAY2::element_type> \
+    (x, y, LOOP, LOOP, LOOP); }
 
 #define BSXFUN_REL_DEF_MXLOOP(OP, ARRAY, LOOP) \
   BSXFUN_REL_DEF(OP, ARRAY) \
-  { return do_bsxfun_op<boolNDArray, ARRAY, ARRAY> (x, y, LOOP, LOOP, LOOP); }
+  { return do_bsxfun_op<bool, ARRAY::element_type, ARRAY::element_type> \
+    (x, y, LOOP, LOOP, LOOP); }
 
 #define BSXFUN_STDOP_DEFS_MXLOOP(ARRAY) \
   BSXFUN_OP_DEF_MXLOOP (add, ARRAY, mx_inline_add) \
--- a/liboctave/chMatrix.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/chMatrix.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -205,13 +205,13 @@
 boolMatrix
 charMatrix::all (int dim) const
 {
-  return do_mx_red_op<boolMatrix, char> (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, char> (*this, dim, mx_inline_all);
 }
 
 boolMatrix
 charMatrix::any (int dim) const
 {
-  return do_mx_red_op<boolMatrix, char> (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, char> (*this, dim, mx_inline_any);
 }
 
 MS_CMP_OPS (charMatrix, char)
--- a/liboctave/chNDArray.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/chNDArray.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -39,13 +39,13 @@
 boolNDArray
 charNDArray::all (int dim) const
 {
-  return do_mx_red_op<boolMatrix, char> (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, char> (*this, dim, mx_inline_all);
 }
 
 boolNDArray
 charNDArray::any (int dim) const
 {
-  return do_mx_red_op<boolMatrix, char> (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, char> (*this, dim, mx_inline_any);
 }
 
 charNDArray
--- a/liboctave/dMatrix.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/dMatrix.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -2609,7 +2609,7 @@
 boolMatrix
 Matrix::operator ! (void) const
 {
-  return do_mx_unary_op<boolMatrix, Matrix> (*this, mx_inline_not);
+  return do_mx_unary_op<bool, double> (*this, mx_inline_not);
 }
 
 // column vector by row vector -> matrix operations
@@ -2780,43 +2780,43 @@
 boolMatrix
 Matrix::all (int dim) const
 {
-  return do_mx_red_op<boolMatrix, double> (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, double> (*this, dim, mx_inline_all);
 }
 
 boolMatrix
 Matrix::any (int dim) const
 {
-  return do_mx_red_op<boolMatrix, double> (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, double> (*this, dim, mx_inline_any);
 }
 
 Matrix
 Matrix::cumprod (int dim) const
 {
-  return do_mx_cum_op<Matrix, double> (*this, dim, mx_inline_cumprod);
+  return do_mx_cum_op<double, double> (*this, dim, mx_inline_cumprod);
 }
 
 Matrix
 Matrix::cumsum (int dim) const
 {
-  return do_mx_cum_op<Matrix, double> (*this, dim, mx_inline_cumsum);
+  return do_mx_cum_op<double, double> (*this, dim, mx_inline_cumsum);
 }
 
 Matrix
 Matrix::prod (int dim) const
 {
-  return do_mx_red_op<Matrix, double> (*this, dim, mx_inline_prod);
+  return do_mx_red_op<double, double> (*this, dim, mx_inline_prod);
 }
 
 Matrix
 Matrix::sum (int dim) const
 {
-  return do_mx_red_op<Matrix, double> (*this, dim, mx_inline_sum);
+  return do_mx_red_op<double, double> (*this, dim, mx_inline_sum);
 }
 
 Matrix
 Matrix::sumsq (int dim) const
 {
-  return do_mx_red_op<Matrix, double> (*this, dim, mx_inline_sumsq);
+  return do_mx_red_op<double, double> (*this, dim, mx_inline_sumsq);
 }
 
 Matrix
--- a/liboctave/dNDArray.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/dNDArray.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -541,7 +541,7 @@
 boolNDArray
 NDArray::operator ! (void) const
 {
-  return do_mx_unary_op<boolNDArray, NDArray> (*this, mx_inline_not);
+  return do_mx_unary_op<bool, double> (*this, mx_inline_not);
 }
 
 bool
@@ -706,103 +706,103 @@
 boolNDArray
 NDArray::all (int dim) const
 {
-  return do_mx_red_op<boolNDArray, double> (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, double> (*this, dim, mx_inline_all);
 }
 
 boolNDArray
 NDArray::any (int dim) const
 {
-  return do_mx_red_op<boolNDArray, double> (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, double> (*this, dim, mx_inline_any);
 }
 
 NDArray
 NDArray::cumprod (int dim) const
 {
-  return do_mx_cum_op<NDArray, double> (*this, dim, mx_inline_cumprod);
+  return do_mx_cum_op<double, double> (*this, dim, mx_inline_cumprod);
 }
 
 NDArray
 NDArray::cumsum (int dim) const
 {
-  return do_mx_cum_op<NDArray, double> (*this, dim, mx_inline_cumsum);
+  return do_mx_cum_op<double, double> (*this, dim, mx_inline_cumsum);
 }
 
 NDArray
 NDArray::prod (int dim) const
 {
-  return do_mx_red_op<NDArray, double> (*this, dim, mx_inline_prod);
+  return do_mx_red_op<double, double> (*this, dim, mx_inline_prod);
 }
 
 NDArray
 NDArray::sum (int dim) const
 {
-  return do_mx_red_op<NDArray, double> (*this, dim, mx_inline_sum);
+  return do_mx_red_op<double, double> (*this, dim, mx_inline_sum);
 }
 
 NDArray
 NDArray::xsum (int dim) const
 {
-  return do_mx_red_op<NDArray, double> (*this, dim, mx_inline_xsum);
+  return do_mx_red_op<double, double> (*this, dim, mx_inline_xsum);
 }
 
 NDArray
 NDArray::sumsq (int dim) const
 {
-  return do_mx_red_op<NDArray, double> (*this, dim, mx_inline_sumsq);
+  return do_mx_red_op<double, double> (*this, dim, mx_inline_sumsq);
 }
 
 NDArray
 NDArray::max (int dim) const
 {
-  return do_mx_minmax_op<NDArray> (*this, dim, mx_inline_max);
+  return do_mx_minmax_op<double> (*this, dim, mx_inline_max);
 }
 
 NDArray
 NDArray::max (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_minmax_op<NDArray> (*this, idx_arg, dim, mx_inline_max);
+  return do_mx_minmax_op<double> (*this, idx_arg, dim, mx_inline_max);
 }
 
 NDArray
 NDArray::min (int dim) const
 {
-  return do_mx_minmax_op<NDArray> (*this, dim, mx_inline_min);
+  return do_mx_minmax_op<double> (*this, dim, mx_inline_min);
 }
 
 NDArray
 NDArray::min (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_minmax_op<NDArray> (*this, idx_arg, dim, mx_inline_min);
+  return do_mx_minmax_op<double> (*this, idx_arg, dim, mx_inline_min);
 }
 
 NDArray
 NDArray::cummax (int dim) const
 {
-  return do_mx_cumminmax_op<NDArray> (*this, dim, mx_inline_cummax);
+  return do_mx_cumminmax_op<double> (*this, dim, mx_inline_cummax);
 }
 
 NDArray
 NDArray::cummax (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_cumminmax_op<NDArray> (*this, idx_arg, dim, mx_inline_cummax);
+  return do_mx_cumminmax_op<double> (*this, idx_arg, dim, mx_inline_cummax);
 }
 
 NDArray
 NDArray::cummin (int dim) const
 {
-  return do_mx_cumminmax_op<NDArray> (*this, dim, mx_inline_cummin);
+  return do_mx_cumminmax_op<double> (*this, dim, mx_inline_cummin);
 }
 
 NDArray
 NDArray::cummin (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_cumminmax_op<NDArray> (*this, idx_arg, dim, mx_inline_cummin);
+  return do_mx_cumminmax_op<double> (*this, idx_arg, dim, mx_inline_cummin);
 }
 
 NDArray
 NDArray::diff (octave_idx_type order, int dim) const
 {
-  return do_mx_diff_op<NDArray> (*this, dim, order, mx_inline_diff);
+  return do_mx_diff_op<double> (*this, dim, order, mx_inline_diff);
 }
 
 NDArray
@@ -861,13 +861,13 @@
 NDArray
 real (const ComplexNDArray& a)
 {
-  return do_mx_unary_op<NDArray, ComplexNDArray> (a, mx_inline_real);
+  return do_mx_unary_op<double, Complex> (a, mx_inline_real);
 }
 
 NDArray
 imag (const ComplexNDArray& a)
 {
-  return do_mx_unary_op<NDArray, ComplexNDArray> (a, mx_inline_imag);
+  return do_mx_unary_op<double, Complex> (a, mx_inline_imag);
 }
 
 NDArray&
@@ -887,25 +887,25 @@
 NDArray
 NDArray::abs (void) const
 {
-  return do_mx_unary_map<NDArray, NDArray, std::abs> (*this);
+  return do_mx_unary_map<double, double, std::abs> (*this);
 }
 
 boolNDArray
 NDArray::isnan (void) const
 {
-  return do_mx_unary_map<boolNDArray, NDArray, xisnan> (*this);
+  return do_mx_unary_map<bool, double, xisnan> (*this);
 }
 
 boolNDArray
 NDArray::isinf (void) const
 {
-  return do_mx_unary_map<boolNDArray, NDArray, xisinf> (*this);
+  return do_mx_unary_map<bool, double, xisinf> (*this);
 }
 
 boolNDArray
 NDArray::isfinite (void) const
 {
-  return do_mx_unary_map<boolNDArray, NDArray, xfinite> (*this);
+  return do_mx_unary_map<bool, double, xfinite> (*this);
 }
 
 Matrix
--- a/liboctave/fCMatrix.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/fCMatrix.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -3062,7 +3062,7 @@
 boolMatrix
 FloatComplexMatrix::operator ! (void) const
 {
-  return do_mx_unary_op<boolMatrix, FloatComplexMatrix> (*this, mx_inline_not);
+  return do_mx_unary_op<bool, FloatComplex> (*this, mx_inline_not);
 }
 
 // other operations
@@ -3195,43 +3195,43 @@
 boolMatrix
 FloatComplexMatrix::all (int dim) const
 {
-  return do_mx_red_op<boolMatrix, FloatComplex> (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, FloatComplex> (*this, dim, mx_inline_all);
 }
 
 boolMatrix
 FloatComplexMatrix::any (int dim) const
 {
-  return do_mx_red_op<boolMatrix, FloatComplex> (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, FloatComplex> (*this, dim, mx_inline_any);
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::cumprod (int dim) const
 {
-  return do_mx_cum_op<FloatComplexMatrix, FloatComplex> (*this, dim, mx_inline_cumprod);
+  return do_mx_cum_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_cumprod);
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::cumsum (int dim) const
 {
-  return do_mx_cum_op<FloatComplexMatrix, FloatComplex> (*this, dim, mx_inline_cumsum);
+  return do_mx_cum_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_cumsum);
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::prod (int dim) const
 {
-  return do_mx_red_op<FloatComplexMatrix, FloatComplex> (*this, dim, mx_inline_prod);
+  return do_mx_red_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_prod);
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::sum (int dim) const
 {
-  return do_mx_red_op<FloatComplexMatrix, FloatComplex> (*this, dim, mx_inline_sum);
+  return do_mx_red_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_sum);
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::sumsq (int dim) const
 {
-  return do_mx_red_op<FloatMatrix, FloatComplex> (*this, dim, mx_inline_sumsq);
+  return do_mx_red_op<float, FloatComplex> (*this, dim, mx_inline_sumsq);
 }
 
 FloatMatrix FloatComplexMatrix::abs (void) const
--- a/liboctave/fCNDArray.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/fCNDArray.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -495,7 +495,7 @@
 boolNDArray
 FloatComplexNDArray::operator ! (void) const
 {
-  return do_mx_unary_op<boolNDArray, FloatComplexNDArray> (*this, mx_inline_not);
+  return do_mx_unary_op<bool, FloatComplex> (*this, mx_inline_not);
 }
 
 // FIXME -- this is not quite the right thing.
@@ -615,55 +615,55 @@
 boolNDArray
 FloatComplexNDArray::all (int dim) const
 {
-  return do_mx_red_op<boolNDArray, FloatComplex> (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, FloatComplex> (*this, dim, mx_inline_all);
 }
 
 boolNDArray
 FloatComplexNDArray::any (int dim) const
 {
-  return do_mx_red_op<boolNDArray, FloatComplex> (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, FloatComplex> (*this, dim, mx_inline_any);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::cumprod (int dim) const
 {
-  return do_mx_cum_op<FloatComplexNDArray, FloatComplex> (*this, dim, mx_inline_cumprod);
+  return do_mx_cum_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_cumprod);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::cumsum (int dim) const
 {
-  return do_mx_cum_op<FloatComplexNDArray, FloatComplex> (*this, dim, mx_inline_cumsum);
+  return do_mx_cum_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_cumsum);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::prod (int dim) const
 {
-  return do_mx_red_op<FloatComplexNDArray, FloatComplex> (*this, dim, mx_inline_prod);
+  return do_mx_red_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_prod);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::sum (int dim) const
 {
-  return do_mx_red_op<FloatComplexNDArray, FloatComplex> (*this, dim, mx_inline_sum);
+  return do_mx_red_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_sum);
 }
 
 ComplexNDArray
 FloatComplexNDArray::dsum (int dim) const
 {
-  return do_mx_red_op<ComplexNDArray, FloatComplex> (*this, dim, mx_inline_dsum);
+  return do_mx_red_op<Complex, FloatComplex> (*this, dim, mx_inline_dsum);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::sumsq (int dim) const
 {
-  return do_mx_red_op<FloatNDArray, FloatComplex> (*this, dim, mx_inline_sumsq);
+  return do_mx_red_op<float, FloatComplex> (*this, dim, mx_inline_sumsq);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::diff (octave_idx_type order, int dim) const
 {
-  return do_mx_diff_op<FloatComplexNDArray> (*this, dim, order, mx_inline_diff);
+  return do_mx_diff_op<FloatComplex> (*this, dim, order, mx_inline_diff);
 }
 
 FloatComplexNDArray
@@ -697,79 +697,79 @@
 FloatComplexNDArray
 FloatComplexNDArray::max (int dim) const
 {
-  return do_mx_minmax_op<FloatComplexNDArray> (*this, dim, mx_inline_max);
+  return do_mx_minmax_op<FloatComplex> (*this, dim, mx_inline_max);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::max (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_minmax_op<FloatComplexNDArray> (*this, idx_arg, dim, mx_inline_max);
+  return do_mx_minmax_op<FloatComplex> (*this, idx_arg, dim, mx_inline_max);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::min (int dim) const
 {
-  return do_mx_minmax_op<FloatComplexNDArray> (*this, dim, mx_inline_min);
+  return do_mx_minmax_op<FloatComplex> (*this, dim, mx_inline_min);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::min (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_minmax_op<FloatComplexNDArray> (*this, idx_arg, dim, mx_inline_min);
+  return do_mx_minmax_op<FloatComplex> (*this, idx_arg, dim, mx_inline_min);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::cummax (int dim) const
 {
-  return do_mx_cumminmax_op<FloatComplexNDArray> (*this, dim, mx_inline_cummax);
+  return do_mx_cumminmax_op<FloatComplex> (*this, dim, mx_inline_cummax);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::cummax (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_cumminmax_op<FloatComplexNDArray> (*this, idx_arg, dim, mx_inline_cummax);
+  return do_mx_cumminmax_op<FloatComplex> (*this, idx_arg, dim, mx_inline_cummax);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::cummin (int dim) const
 {
-  return do_mx_cumminmax_op<FloatComplexNDArray> (*this, dim, mx_inline_cummin);
+  return do_mx_cumminmax_op<FloatComplex> (*this, dim, mx_inline_cummin);
 }
 
 FloatComplexNDArray
 FloatComplexNDArray::cummin (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_cumminmax_op<FloatComplexNDArray> (*this, idx_arg, dim, mx_inline_cummin);
+  return do_mx_cumminmax_op<FloatComplex> (*this, idx_arg, dim, mx_inline_cummin);
 }
 
 FloatNDArray
 FloatComplexNDArray::abs (void) const
 {
-  return do_mx_unary_map<FloatNDArray, FloatComplexNDArray, std::abs> (*this);
+  return do_mx_unary_map<float, FloatComplex, std::abs> (*this);
 }
 
 boolNDArray
 FloatComplexNDArray::isnan (void) const
 {
-  return do_mx_unary_map<boolNDArray, FloatComplexNDArray, xisnan> (*this);
+  return do_mx_unary_map<bool, FloatComplex, xisnan> (*this);
 }
 
 boolNDArray
 FloatComplexNDArray::isinf (void) const
 {
-  return do_mx_unary_map<boolNDArray, FloatComplexNDArray, xisinf> (*this);
+  return do_mx_unary_map<bool, FloatComplex, xisinf> (*this);
 }
 
 boolNDArray
 FloatComplexNDArray::isfinite (void) const
 {
-  return do_mx_unary_map<boolNDArray, FloatComplexNDArray, xfinite> (*this);
+  return do_mx_unary_map<bool, FloatComplex, xfinite> (*this);
 }
 
 FloatComplexNDArray
 conj (const FloatComplexNDArray& a)
 {
-  return do_mx_unary_map<FloatComplexNDArray, FloatComplexNDArray, std::conj> (a);
+  return do_mx_unary_map<FloatComplex, FloatComplex, std::conj> (a);
 }
 
 FloatComplexNDArray&
@@ -925,7 +925,7 @@
   if (a.is_shared ())
     a = a * s;
   else
-    do_ms_inplace_op<FloatComplexNDArray, float> (a, s, mx_inline_mul2);
+    do_ms_inplace_op<FloatComplex, float> (a, s, mx_inline_mul2);
   return a;
 }
 
@@ -934,7 +934,7 @@
   if (a.is_shared ())
     a = a / s;
   else
-    do_ms_inplace_op<FloatComplexNDArray, float> (a, s, mx_inline_div2);
+    do_ms_inplace_op<FloatComplex, float> (a, s, mx_inline_div2);
   return a;
 }
 
--- a/liboctave/fMatrix.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/fMatrix.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -2608,7 +2608,7 @@
 boolMatrix
 FloatMatrix::operator ! (void) const
 {
-  return do_mx_unary_op<boolMatrix, FloatMatrix> (*this, mx_inline_not);
+  return do_mx_unary_op<bool, float> (*this, mx_inline_not);
 }
 
 // column vector by row vector -> matrix operations
@@ -2779,43 +2779,43 @@
 boolMatrix
 FloatMatrix::all (int dim) const
 {
-  return do_mx_red_op<boolMatrix, float> (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, float> (*this, dim, mx_inline_all);
 }
 
 boolMatrix
 FloatMatrix::any (int dim) const
 {
-  return do_mx_red_op<boolMatrix, float> (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, float> (*this, dim, mx_inline_any);
 }
 
 FloatMatrix
 FloatMatrix::cumprod (int dim) const
 {
-  return do_mx_cum_op<FloatMatrix, float> (*this, dim, mx_inline_cumprod);
+  return do_mx_cum_op<float, float> (*this, dim, mx_inline_cumprod);
 }
 
 FloatMatrix
 FloatMatrix::cumsum (int dim) const
 {
-  return do_mx_cum_op<FloatMatrix, float> (*this, dim, mx_inline_cumsum);
+  return do_mx_cum_op<float, float> (*this, dim, mx_inline_cumsum);
 }
 
 FloatMatrix
 FloatMatrix::prod (int dim) const
 {
-  return do_mx_red_op<FloatMatrix, float> (*this, dim, mx_inline_prod);
+  return do_mx_red_op<float, float> (*this, dim, mx_inline_prod);
 }
 
 FloatMatrix
 FloatMatrix::sum (int dim) const
 {
-  return do_mx_red_op<FloatMatrix, float> (*this, dim, mx_inline_sum);
+  return do_mx_red_op<float, float> (*this, dim, mx_inline_sum);
 }
 
 FloatMatrix
 FloatMatrix::sumsq (int dim) const
 {
-  return do_mx_red_op<FloatMatrix, float> (*this, dim, mx_inline_sumsq);
+  return do_mx_red_op<float, float> (*this, dim, mx_inline_sumsq);
 }
 
 FloatMatrix
--- a/liboctave/fNDArray.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/fNDArray.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -499,7 +499,7 @@
 boolNDArray
 FloatNDArray::operator ! (void) const
 {
-  return do_mx_unary_op<boolNDArray, FloatNDArray> (*this, mx_inline_not);
+  return do_mx_unary_op<bool, float> (*this, mx_inline_not);
 }
 
 bool
@@ -664,103 +664,103 @@
 boolNDArray
 FloatNDArray::all (int dim) const
 {
-  return do_mx_red_op<boolNDArray, float> (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, float> (*this, dim, mx_inline_all);
 }
 
 boolNDArray
 FloatNDArray::any (int dim) const
 {
-  return do_mx_red_op<boolNDArray, float> (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, float> (*this, dim, mx_inline_any);
 }
 
 FloatNDArray
 FloatNDArray::cumprod (int dim) const
 {
-  return do_mx_cum_op<FloatNDArray, float> (*this, dim, mx_inline_cumprod);
+  return do_mx_cum_op<float, float> (*this, dim, mx_inline_cumprod);
 }
 
 FloatNDArray
 FloatNDArray::cumsum (int dim) const
 {
-  return do_mx_cum_op<FloatNDArray, float> (*this, dim, mx_inline_cumsum);
+  return do_mx_cum_op<float, float> (*this, dim, mx_inline_cumsum);
 }
 
 FloatNDArray
 FloatNDArray::prod (int dim) const
 {
-  return do_mx_red_op<FloatNDArray, float> (*this, dim, mx_inline_prod);
+  return do_mx_red_op<float, float> (*this, dim, mx_inline_prod);
 }
 
 FloatNDArray
 FloatNDArray::sum (int dim) const
 {
-  return do_mx_red_op<FloatNDArray, float> (*this, dim, mx_inline_sum);
+  return do_mx_red_op<float, float> (*this, dim, mx_inline_sum);
 }
 
 NDArray
 FloatNDArray::dsum (int dim) const
 {
-  return do_mx_red_op<NDArray, float> (*this, dim, mx_inline_dsum);
+  return do_mx_red_op<double, float> (*this, dim, mx_inline_dsum);
 }
 
 FloatNDArray
 FloatNDArray::sumsq (int dim) const
 {
-  return do_mx_red_op<FloatNDArray, float> (*this, dim, mx_inline_sumsq);
+  return do_mx_red_op<float, float> (*this, dim, mx_inline_sumsq);
 }
 
 FloatNDArray
 FloatNDArray::max (int dim) const
 {
-  return do_mx_minmax_op<FloatNDArray> (*this, dim, mx_inline_max);
+  return do_mx_minmax_op<float> (*this, dim, mx_inline_max);
 }
 
 FloatNDArray
 FloatNDArray::max (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_minmax_op<FloatNDArray> (*this, idx_arg, dim, mx_inline_max);
+  return do_mx_minmax_op<float> (*this, idx_arg, dim, mx_inline_max);
 }
 
 FloatNDArray
 FloatNDArray::min (int dim) const
 {
-  return do_mx_minmax_op<FloatNDArray> (*this, dim, mx_inline_min);
+  return do_mx_minmax_op<float> (*this, dim, mx_inline_min);
 }
 
 FloatNDArray
 FloatNDArray::min (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_minmax_op<FloatNDArray> (*this, idx_arg, dim, mx_inline_min);
+  return do_mx_minmax_op<float> (*this, idx_arg, dim, mx_inline_min);
 }
 
 FloatNDArray
 FloatNDArray::cummax (int dim) const
 {
-  return do_mx_cumminmax_op<FloatNDArray> (*this, dim, mx_inline_cummax);
+  return do_mx_cumminmax_op<float> (*this, dim, mx_inline_cummax);
 }
 
 FloatNDArray
 FloatNDArray::cummax (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_cumminmax_op<FloatNDArray> (*this, idx_arg, dim, mx_inline_cummax);
+  return do_mx_cumminmax_op<float> (*this, idx_arg, dim, mx_inline_cummax);
 }
 
 FloatNDArray
 FloatNDArray::cummin (int dim) const
 {
-  return do_mx_cumminmax_op<FloatNDArray> (*this, dim, mx_inline_cummin);
+  return do_mx_cumminmax_op<float> (*this, dim, mx_inline_cummin);
 }
 
 FloatNDArray
 FloatNDArray::cummin (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_cumminmax_op<FloatNDArray> (*this, idx_arg, dim, mx_inline_cummin);
+  return do_mx_cumminmax_op<float> (*this, idx_arg, dim, mx_inline_cummin);
 }
 
 FloatNDArray
 FloatNDArray::diff (octave_idx_type order, int dim) const
 {
-  return do_mx_diff_op<FloatNDArray> (*this, dim, order, mx_inline_diff);
+  return do_mx_diff_op<float> (*this, dim, order, mx_inline_diff);
 }
 
 FloatNDArray
@@ -819,13 +819,13 @@
 FloatNDArray
 real (const FloatComplexNDArray& a)
 {
-  return do_mx_unary_op<FloatNDArray, FloatComplexNDArray> (a, mx_inline_real);
+  return do_mx_unary_op<float, FloatComplex> (a, mx_inline_real);
 }
 
 FloatNDArray
 imag (const FloatComplexNDArray& a)
 {
-  return do_mx_unary_op<FloatNDArray, FloatComplexNDArray> (a, mx_inline_imag);
+  return do_mx_unary_op<float, FloatComplex> (a, mx_inline_imag);
 }
 
 FloatNDArray&
@@ -845,25 +845,25 @@
 FloatNDArray
 FloatNDArray::abs (void) const
 {
-  return do_mx_unary_map<FloatNDArray, FloatNDArray, std::abs> (*this);
+  return do_mx_unary_map<float, float, std::abs> (*this);
 }
 
 boolNDArray
 FloatNDArray::isnan (void) const
 {
-  return do_mx_unary_map<boolNDArray, FloatNDArray, xisnan> (*this);
+  return do_mx_unary_map<bool, float, xisnan> (*this);
 }
 
 boolNDArray
 FloatNDArray::isinf (void) const
 {
-  return do_mx_unary_map<boolNDArray, FloatNDArray, xisinf> (*this);
+  return do_mx_unary_map<bool, float, xisinf> (*this);
 }
 
 boolNDArray
 FloatNDArray::isfinite (void) const
 {
-  return do_mx_unary_map<boolNDArray, FloatNDArray, xfinite> (*this);
+  return do_mx_unary_map<bool, float, xfinite> (*this);
 }
 
 FloatMatrix
--- a/liboctave/intNDArray.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/intNDArray.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -75,14 +75,14 @@
 boolNDArray
 intNDArray<T>::all (int dim) const
 {
-  return do_mx_red_op<boolNDArray, T > (*this, dim, mx_inline_all);
+  return do_mx_red_op<bool, T > (*this, dim, mx_inline_all);
 }
 
 template <class T>
 boolNDArray
 intNDArray<T>::any (int dim) const
 {
-  return do_mx_red_op<boolNDArray, T > (*this, dim, mx_inline_any);
+  return do_mx_red_op<bool, T > (*this, dim, mx_inline_any);
 }
 
 template <class T>
@@ -205,82 +205,82 @@
 intNDArray<T>
 intNDArray<T>::sum (int dim) const
 {
-  return do_mx_red_op<intNDArray<T> , T > (*this, dim, mx_inline_sum);
+  return do_mx_red_op<T, T> (*this, dim, mx_inline_sum);
 }
 
 template <class T>
 NDArray
 intNDArray<T>::dsum (int dim) const
 {
-  return do_mx_red_op<NDArray , T> (*this, dim, mx_inline_dsum);
+  return do_mx_red_op<double, T> (*this, dim, mx_inline_dsum);
 }
 
 template <class T>
 intNDArray<T>
 intNDArray<T>::cumsum (int dim) const
 {
-  return do_mx_cum_op<intNDArray<T> , T > (*this, dim, mx_inline_cumsum);
+  return do_mx_cum_op<T, T> (*this, dim, mx_inline_cumsum);
 }
 
 template <class T>
 intNDArray<T>
 intNDArray<T>::max (int dim) const
 {
-  return do_mx_minmax_op<intNDArray<T> > (*this, dim, mx_inline_max);
+  return do_mx_minmax_op<T> (*this, dim, mx_inline_max);
 }
 
 template <class T>
 intNDArray<T>
 intNDArray<T>::max (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_minmax_op<intNDArray<T> > (*this, idx_arg, dim, mx_inline_max);
+  return do_mx_minmax_op<T> (*this, idx_arg, dim, mx_inline_max);
 }
 
 template <class T>
 intNDArray<T>
 intNDArray<T>::min (int dim) const
 {
-  return do_mx_minmax_op<intNDArray<T> > (*this, dim, mx_inline_min);
+  return do_mx_minmax_op<T> (*this, dim, mx_inline_min);
 }
 
 template <class T>
 intNDArray<T>
 intNDArray<T>::min (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_minmax_op<intNDArray<T> > (*this, idx_arg, dim, mx_inline_min);
+  return do_mx_minmax_op<T> (*this, idx_arg, dim, mx_inline_min);
 }
 
 template <class T>
 intNDArray<T>
 intNDArray<T>::cummax (int dim) const
 {
-  return do_mx_cumminmax_op<intNDArray<T> > (*this, dim, mx_inline_cummax);
+  return do_mx_cumminmax_op<T> (*this, dim, mx_inline_cummax);
 }
 
 template <class T>
 intNDArray<T>
 intNDArray<T>::cummax (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_cumminmax_op<intNDArray<T> > (*this, idx_arg, dim, mx_inline_cummax);
+  return do_mx_cumminmax_op<T> (*this, idx_arg, dim, mx_inline_cummax);
 }
 
 template <class T>
 intNDArray<T>
 intNDArray<T>::cummin (int dim) const
 {
-  return do_mx_cumminmax_op<intNDArray<T> > (*this, dim, mx_inline_cummin);
+  return do_mx_cumminmax_op<T> (*this, dim, mx_inline_cummin);
 }
 
 template <class T>
 intNDArray<T>
 intNDArray<T>::cummin (Array<octave_idx_type>& idx_arg, int dim) const
 {
-  return do_mx_cumminmax_op<intNDArray<T> > (*this, idx_arg, dim, mx_inline_cummin);
+  return do_mx_cumminmax_op<T> (*this, idx_arg, dim, mx_inline_cummin);
 }
 
 template <class T>
 intNDArray<T>
 intNDArray<T>::diff (octave_idx_type order, int dim) const
 {
-  return do_mx_diff_op<intNDArray<T> > (*this, dim, order, mx_inline_diff);
+  return do_mx_diff_op<T> (*this, dim, order, mx_inline_diff);
 }
--- a/liboctave/mx-inlines.cc	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/mx-inlines.cc	Fri Feb 26 09:47:54 2010 +0100
@@ -35,7 +35,7 @@
 #include "oct-cmplx.h"
 #include "oct-locbuf.h"
 #include "oct-inttypes.h"
-#include "Array-util.h"
+#include "Array.h"
 #include "Array-util.h"
 
 // Provides some commonly repeated, basic loop templates.
@@ -298,93 +298,86 @@
 // Appliers. Since these call the operation just once, we pass it as
 // a pointer, to allow the compiler reduce number of instances.
 
-#define AELEMT(ARRAY) typename ARRAY::element_type
-template <class RNDA, class XNDA>
-inline RNDA 
-do_mx_unary_op (const XNDA& x,
-                void (*op) (size_t, AELEMT(RNDA) *,
-                            const AELEMT(XNDA) *))
+template <class R, class X>
+inline Array<R> 
+do_mx_unary_op (const Array<X>& x,
+                void (*op) (size_t, R *, const X *))
 {
-  RNDA r (x.dims ());
-  op (r.length (), r.fortran_vec (), x.data ());
+  Array<R> r (x.dims ());
+  op (r.numel (), r.fortran_vec (), x.data ());
   return r;
 }
 
 // Shortcuts for applying mx_inline_map.
 
-template <class RNDA, class XNDA, AELEMT(RNDA) fun (AELEMT(XNDA))>
-inline RNDA 
-do_mx_unary_map (const XNDA& x)
+template <class R, class X, R fun (X)>
+inline Array<R> 
+do_mx_unary_map (const Array<X>& x)
 {
-  return do_mx_unary_op<RNDA, XNDA> (x, mx_inline_map<AELEMT(RNDA), AELEMT(XNDA), fun>);
+  return do_mx_unary_op<R, X> (x, mx_inline_map<R, X, fun>);
 }
 
-template <class RNDA, class XNDA, AELEMT(RNDA) fun (const AELEMT(XNDA)&)>
-inline RNDA 
-do_mx_unary_map (const XNDA& x)
+template <class R, class X, R fun (const X&)>
+inline Array<R> 
+do_mx_unary_map (const Array<X>& x)
 {
-  return do_mx_unary_op<RNDA, XNDA> (x, mx_inline_map<AELEMT(RNDA), AELEMT(XNDA), fun>);
+  return do_mx_unary_op<R, X> (x, mx_inline_map<R, X, fun>);
 }
 
-template <class RNDA>
-inline RNDA&
-do_mx_inplace_op (RNDA& r,
-                  void (*op) (size_t, AELEMT(RNDA) *))
+template <class R>
+inline Array<R>&
+do_mx_inplace_op (Array<R>& r,
+                  void (*op) (size_t, R *))
 {
   op (r.numel (), r.fortran_vec ());
   return r;
 }
 
 
-template <class RNDA, class XNDA, class YNDA>
-inline RNDA 
-do_mm_binary_op (const XNDA& x, const YNDA& y,
-                 void (*op) (size_t, AELEMT(RNDA) *,
-                             const AELEMT(XNDA) *,
-                             const AELEMT(YNDA) *),
+template <class R, class X, class Y>
+inline Array<R> 
+do_mm_binary_op (const Array<X>& x, const Array<Y>& y,
+                 void (*op) (size_t, R *, const X *, const Y *),
                  const char *opname)
 {
   dim_vector dx = x.dims (), dy = y.dims ();
   if (dx == dy)
     {
-      RNDA r (dx);
+      Array<R> r (dx);
       op (r.length (), r.fortran_vec (), x.data (), y.data ());
       return r;
     }
   else
     {
       gripe_nonconformant (opname, dx, dy);
-      return RNDA ();
+      return Array<R> ();
     }
 }
 
-template <class RNDA, class XNDA, class YS>
-inline RNDA 
-do_ms_binary_op (const XNDA& x, const YS& y,
-                 void (*op) (size_t, AELEMT(RNDA) *,
-                             const AELEMT(XNDA) *, YS))
+template <class R, class X, class Y>
+inline Array<R> 
+do_ms_binary_op (const Array<X>& x, const Y& y,
+                 void (*op) (size_t, R *, const X *, Y))
 {
-  RNDA r (x.dims ());
+  Array<R> r (x.dims ());
   op (r.length (), r.fortran_vec (), x.data (), y);
   return r;
 }
 
-template <class RNDA, class XS, class YNDA>
-inline RNDA 
-do_sm_binary_op (const XS& x, const YNDA& y,
-                 void (*op) (size_t, AELEMT(RNDA) *, XS,
-                             const AELEMT(YNDA) *))
+template <class R, class X, class Y>
+inline Array<R> 
+do_sm_binary_op (const X& x, const Array<Y>& y,
+                 void (*op) (size_t, R *, X, const Y *))
 {
-  RNDA r (y.dims ());
+  Array<R> r (y.dims ());
   op (r.length (), r.fortran_vec (), x, y.data ());
   return r;
 }
 
-template <class RNDA, class XNDA>
-inline RNDA& 
-do_mm_inplace_op (RNDA& r, const XNDA& x,
-                  void (*op) (size_t, AELEMT(RNDA) *,
-                              const AELEMT(XNDA) *),
+template <class R, class X>
+inline Array<R>& 
+do_mm_inplace_op (Array<R>& r, const Array<X>& x,
+                  void (*op) (size_t, R *, const X *),
                   const char *opname)
 {
   dim_vector dr = r.dims (), dx = x.dims ();
@@ -395,10 +388,10 @@
   return r;
 }
 
-template <class RNDA, class XS>
-inline RNDA& 
-do_ms_inplace_op (RNDA& r, const XS& x,
-                  void (*op) (size_t, AELEMT(RNDA) *, XS))
+template <class R, class X>
+inline Array<R>& 
+do_ms_inplace_op (Array<R>& r, const X& x,
+                  void (*op) (size_t, R *, X))
 {
   op (r.length (), r.fortran_vec (), x);
   return r;
@@ -1182,11 +1175,11 @@
 // FIXME: is this the best design? C++ gives a lot of options here...
 // maybe it can be done without an explicit parameter?
 
-template <class ArrayType, class T>
-inline ArrayType
+template <class R, class T>
+inline Array<R>
 do_mx_red_op (const Array<T>& src, int dim,
-              void (*mx_red_op) (const T *, AELEMT(ArrayType) *,
-                                 octave_idx_type, octave_idx_type, octave_idx_type))
+              void (*mx_red_op) (const T *, R *, octave_idx_type, 
+                                 octave_idx_type, octave_idx_type))
 {
   octave_idx_type l, n, u;
   dim_vector dims = src.dims ();
@@ -1200,33 +1193,53 @@
   if (dim < dims.length ()) dims(dim) = 1;
   dims.chop_trailing_singletons ();
 
-  ArrayType ret (dims);
+  Array<R> ret (dims);
   mx_red_op (src.data (), ret.fortran_vec (), l, n, u);
 
   return ret;
 }
 
-template <class ArrayType, class T>
-inline ArrayType
+template <class R, class T>
+inline Array<R>
 do_mx_cum_op (const Array<T>& src, int dim,
-              void (*mx_cum_op) (const T *, AELEMT(ArrayType) *,
-                                 octave_idx_type, octave_idx_type, octave_idx_type))
+              void (*mx_cum_op) (const T *, R *, octave_idx_type, 
+                                 octave_idx_type, octave_idx_type))
 {
   octave_idx_type l, n, u;
   dim_vector dims = src.dims ();
   get_extent_triplet (dims, dim, l, n, u);
 
   // Cumulative operation doesn't reduce the array size.
-  ArrayType ret (dims);
+  Array<R> ret (dims);
   mx_cum_op (src.data (), ret.fortran_vec (), l, n, u);
 
   return ret;
 }
 
-template <class ArrayType>
-inline ArrayType
-do_mx_minmax_op (const ArrayType& src, int dim,
-                 void (*mx_minmax_op) (const AELEMT(ArrayType) *, AELEMT(ArrayType) *,
+template <class R>
+inline Array<R>
+do_mx_minmax_op (const Array<R>& src, int dim,
+                 void (*mx_minmax_op) (const R *, R *, octave_idx_type, 
+                                       octave_idx_type, octave_idx_type))
+{
+  octave_idx_type l, n, u;
+  dim_vector dims = src.dims ();
+  get_extent_triplet (dims, dim, l, n, u);
+
+  // If the dimension is zero, we don't do anything.
+  if (dim < dims.length () && dims(dim) != 0) dims(dim) = 1;
+  dims.chop_trailing_singletons ();
+
+  Array<R> ret (dims);
+  mx_minmax_op (src.data (), ret.fortran_vec (), l, n, u);
+
+  return ret;
+}
+
+template <class R>
+inline Array<R>
+do_mx_minmax_op (const Array<R>& src, Array<octave_idx_type>& idx, int dim,
+                 void (*mx_minmax_op) (const R *, R *, octave_idx_type *,
                                        octave_idx_type, octave_idx_type, octave_idx_type))
 {
   octave_idx_type l, n, u;
@@ -1237,28 +1250,7 @@
   if (dim < dims.length () && dims(dim) != 0) dims(dim) = 1;
   dims.chop_trailing_singletons ();
 
-  ArrayType ret (dims);
-  mx_minmax_op (src.data (), ret.fortran_vec (), l, n, u);
-
-  return ret;
-}
-
-template <class ArrayType>
-inline ArrayType
-do_mx_minmax_op (const ArrayType& src, Array<octave_idx_type>& idx, int dim,
-                 void (*mx_minmax_op) (const AELEMT(ArrayType) *, AELEMT(ArrayType) *,
-                                       octave_idx_type *,
-                                       octave_idx_type, octave_idx_type, octave_idx_type))
-{
-  octave_idx_type l, n, u;
-  dim_vector dims = src.dims ();
-  get_extent_triplet (dims, dim, l, n, u);
-
-  // If the dimension is zero, we don't do anything.
-  if (dim < dims.length () && dims(dim) != 0) dims(dim) = 1;
-  dims.chop_trailing_singletons ();
-
-  ArrayType ret (dims);
+  Array<R> ret (dims);
   if (idx.dims () != dims) idx = Array<octave_idx_type> (dims);
 
   mx_minmax_op (src.data (), ret.fortran_vec (), idx.fortran_vec (),
@@ -1267,34 +1259,33 @@
   return ret;
 }
 
-template <class ArrayType>
-inline ArrayType
-do_mx_cumminmax_op (const ArrayType& src, int dim,
-                    void (*mx_cumminmax_op) (const AELEMT(ArrayType) *, AELEMT(ArrayType) *,
+template <class R>
+inline Array<R>
+do_mx_cumminmax_op (const Array<R>& src, int dim,
+                    void (*mx_cumminmax_op) (const R *, R *, octave_idx_type, 
+                                             octave_idx_type, octave_idx_type))
+{
+  octave_idx_type l, n, u;
+  dim_vector dims = src.dims ();
+  get_extent_triplet (dims, dim, l, n, u);
+
+  Array<R> ret (dims);
+  mx_cumminmax_op (src.data (), ret.fortran_vec (), l, n, u);
+
+  return ret;
+}
+
+template <class R>
+inline Array<R>
+do_mx_cumminmax_op (const Array<R>& src, Array<octave_idx_type>& idx, int dim,
+                    void (*mx_cumminmax_op) (const R *, R *, octave_idx_type *,
                                              octave_idx_type, octave_idx_type, octave_idx_type))
 {
   octave_idx_type l, n, u;
   dim_vector dims = src.dims ();
   get_extent_triplet (dims, dim, l, n, u);
 
-  ArrayType ret (dims);
-  mx_cumminmax_op (src.data (), ret.fortran_vec (), l, n, u);
-
-  return ret;
-}
-
-template <class ArrayType>
-inline ArrayType
-do_mx_cumminmax_op (const ArrayType& src, Array<octave_idx_type>& idx, int dim,
-                    void (*mx_cumminmax_op) (const AELEMT(ArrayType) *, AELEMT(ArrayType) *,
-                                             octave_idx_type *,
-                                             octave_idx_type, octave_idx_type, octave_idx_type))
-{
-  octave_idx_type l, n, u;
-  dim_vector dims = src.dims ();
-  get_extent_triplet (dims, dim, l, n, u);
-
-  ArrayType ret (dims);
+  Array<R> ret (dims);
   if (idx.dims () != dims) idx = Array<octave_idx_type> (dims);
 
   mx_cumminmax_op (src.data (), ret.fortran_vec (), idx.fortran_vec (),
@@ -1303,10 +1294,10 @@
   return ret;
 }
 
-template <class ArrayType>
-inline ArrayType
-do_mx_diff_op (const ArrayType& src, int dim, octave_idx_type order,
-               void (*mx_diff_op) (const AELEMT(ArrayType) *, AELEMT(ArrayType) *,
+template <class R>
+inline Array<R>
+do_mx_diff_op (const Array<R>& src, int dim, octave_idx_type order,
+               void (*mx_diff_op) (const R *, R *,
                                    octave_idx_type, octave_idx_type, octave_idx_type,
                                    octave_idx_type))
 {
@@ -1323,14 +1314,14 @@
   if (dims(dim) <= order)
     {
       dims (dim) = 0;
-      return ArrayType (dims);
+      return Array<R> (dims);
     }
   else
     {
       dims(dim) -= order;
     }
 
-  ArrayType ret (dims);
+  Array<R> ret (dims);
   mx_diff_op (src.data (), ret.fortran_vec (), l, n, u, order);
 
   return ret;
--- a/liboctave/mx-op-defs.h	Thu Feb 25 15:41:20 2010 -0500
+++ b/liboctave/mx-op-defs.h	Fri Feb 26 09:47:54 2010 +0100
@@ -35,7 +35,7 @@
   R \
   F (const V& v, const S& s) \
   { \
-    return do_ms_binary_op<R, V, S> (v, s, OP); \
+    return do_ms_binary_op<R::element_type, V::element_type, S> (v, s, OP); \
   }
 
 #define VS_BIN_OPS(R, V, S) \
@@ -50,7 +50,7 @@
   R \
   F (const S& s, const V& v) \
   { \
-    return do_sm_binary_op<R, S, V> (s, v, OP); \
+    return do_sm_binary_op<R::element_type, S, V::element_type> (s, v, OP); \
   }
 
 #define SV_BIN_OPS(R, S, V) \
@@ -65,7 +65,7 @@
   R \
   F (const V1& v1, const V2& v2) \
   { \
-    return do_mm_binary_op<R, V1, V2> (v1, v2, OP, #F); \
+    return do_mm_binary_op<R::element_type, V1::element_type, V2::element_type> (v1, v2, OP, #F); \
   }
 
 #define VV_BIN_OPS(R, V1, V2) \
@@ -80,7 +80,7 @@
   R \
   OP (const M& m, const S& s) \
   { \
-    return do_ms_binary_op<R, M, S> (m, s, F); \
+    return do_ms_binary_op<R::element_type, M::element_type, S> (m, s, F); \
   }
 
 #define MS_BIN_OPS(R, M, S) \
@@ -93,7 +93,7 @@
   boolMatrix \
   F (const M& m, const S& s) \
   { \
-    return do_ms_binary_op<boolMatrix, M, S> (m, s, OP); \
+    return do_ms_binary_op<bool, M::element_type, S> (m, s, OP); \
   }
 
 #define MS_CMP_OPS(M, S) \
@@ -108,7 +108,7 @@
   boolMatrix \
   F (const M& m, const S& s) \
   { \
-    return do_ms_binary_op<boolMatrix, M, S> (m, s, OP); \
+    return do_ms_binary_op<bool, M::element_type, S> (m, s, OP); \
   }
 
 #define MS_BOOL_OPS(M, S) \
@@ -121,7 +121,7 @@
   R \
   OP (const S& s, const M& m) \
   { \
-    return do_sm_binary_op<R, S, M> (s, m, F); \
+    return do_sm_binary_op<R::element_type, S, M::element_type> (s, m, F); \
   }
 
 #define SM_BIN_OPS(R, S, M) \
@@ -134,7 +134,7 @@
   boolMatrix \
   F (const S& s, const M& m) \
   { \
-    return do_sm_binary_op<boolMatrix, S, M> (s, m, OP); \
+    return do_sm_binary_op<bool, S, M::element_type> (s, m, OP); \
   }
 
 #define SM_CMP_OPS(S, M) \
@@ -149,7 +149,7 @@
   boolMatrix \
   F (const S& s, const M& m) \
   { \
-    return do_sm_binary_op<boolMatrix, S, M> (s, m, OP); \
+    return do_sm_binary_op<bool, S, M::element_type> (s, m, OP); \
   }
 
 #define SM_BOOL_OPS(S, M) \
@@ -162,7 +162,7 @@
   R \
   OP (const M1& m1, const M2& m2) \
   { \
-    return do_mm_binary_op<R, M1, M2> (m1, m2, F, #OP); \
+    return do_mm_binary_op<R::element_type, M1::element_type, M2::element_type> (m1, m2, F, #OP); \
   }
 
 #define MM_BIN_OPS(R, M1, M2) \
@@ -175,7 +175,7 @@
   boolMatrix \
   F (const M1& m1, const M2& m2) \
   { \
-    return do_mm_binary_op<boolMatrix, M1, M2> (m1, m2, OP, #F); \
+    return do_mm_binary_op<bool, M1::element_type, M2::element_type> (m1, m2, OP, #F); \
   }
 
 #define MM_CMP_OPS(M1, M2) \
@@ -190,7 +190,7 @@
   boolMatrix \
   F (const M1& m1, const M2& m2) \
   { \
-    return do_mm_binary_op<boolMatrix, M1, M2> (m1, m2, OP, #F); \
+    return do_mm_binary_op<bool, M1::element_type, M2::element_type> (m1, m2, OP, #F); \
   }
 
 #define MM_BOOL_OPS(M1, M2) \
@@ -203,7 +203,7 @@
   R \
   OP (const ND& m, const S& s) \
   { \
-    return do_ms_binary_op<R, ND, S> (m, s, F); \
+    return do_ms_binary_op<R::element_type, ND::element_type, S> (m, s, F); \
   }
 
 #define NDS_BIN_OPS(R, ND, S) \
@@ -216,7 +216,7 @@
   boolNDArray \
   F (const ND& m, const S& s) \
   { \
-    return do_ms_binary_op<boolNDArray, ND, S> (m, s, OP); \
+    return do_ms_binary_op<bool, ND::element_type, S> (m, s, OP); \
   }
 
 #define NDS_CMP_OPS(ND, S) \
@@ -231,7 +231,7 @@
   boolNDArray \
   F (const ND& m, const S& s) \
   { \
-    return do_ms_binary_op<boolNDArray, ND, S> (m, s, OP); \
+    return do_ms_binary_op<bool, ND::element_type, S> (m, s, OP); \
   }
 
 #define NDS_BOOL_OPS(ND, S) \
@@ -248,7 +248,7 @@
   R \
   OP (const S& s, const ND& m) \
   { \
-    return do_sm_binary_op<R, S, ND> (s, m, F); \
+    return do_sm_binary_op<R::element_type, S, ND::element_type> (s, m, F); \
   }
 
 #define SND_BIN_OPS(R, S, ND) \
@@ -261,7 +261,7 @@
   boolNDArray \
   F (const S& s, const ND& m) \
   { \
-    return do_sm_binary_op<boolNDArray, S, ND> (s, m, OP); \
+    return do_sm_binary_op<bool, S, ND::element_type> (s, m, OP); \
   }
 
 #define SND_CMP_OPS(S, ND) \
@@ -276,7 +276,7 @@
   boolNDArray \
   F (const S& s, const ND& m) \
   { \
-    return do_sm_binary_op<boolNDArray, S, ND> (s, m, OP); \
+    return do_sm_binary_op<bool, S, ND::element_type> (s, m, OP); \
   }
 
 #define SND_BOOL_OPS(S, ND) \
@@ -293,7 +293,7 @@
   R \
   OP (const ND1& m1, const ND2& m2) \
   { \
-    return do_mm_binary_op<R, ND1, ND2> (m1, m2, F, #OP); \
+    return do_mm_binary_op<R::element_type, ND1::element_type, ND2::element_type> (m1, m2, F, #OP); \
   }
 
 #define NDND_BIN_OPS(R, ND1, ND2) \
@@ -306,7 +306,7 @@
   boolNDArray \
   F (const ND1& m1, const ND2& m2) \
   { \
-    return do_mm_binary_op<boolNDArray, ND1, ND2> (m1, m2, OP, #F); \
+    return do_mm_binary_op<bool, ND1::element_type, ND2::element_type> (m1, m2, OP, #F); \
   }
 
 #define NDND_CMP_OPS(ND1, ND2) \
@@ -321,7 +321,7 @@
   boolNDArray \
   F (const ND1& m1, const ND2& m2) \
   { \
-    return do_mm_binary_op<boolNDArray, ND1, ND2> (m1, m2, OP, #F); \
+    return do_mm_binary_op<bool, ND1::element_type, ND2::element_type> (m1, m2, OP, #F); \
   }
 
 #define NDND_BOOL_OPS(ND1, ND2) \
@@ -550,21 +550,21 @@
 T \
 FCN (S d, const T& m) \
 { \
-  return do_sm_binary_op<T, S, T> (d, m, mx_inline_x##FCN); \
+  return do_sm_binary_op<T::element_type, S, T::element_type> (d, m, mx_inline_x##FCN); \
 }
 
 #define NDS_MINMAX_FCN(FCN, OP, T, S) \
 T \
 FCN (const T& m, S d) \
 { \
-  return do_ms_binary_op<T, T, S> (m, d, mx_inline_x##FCN); \
+  return do_ms_binary_op<T::element_type, T::element_type, S> (m, d, mx_inline_x##FCN); \
 }
 
 #define NDND_MINMAX_FCN(FCN, OP, T, S) \
 T \
 FCN (const T& a, const T& b) \
 { \
-  return do_mm_binary_op<T, T, T> (a, b, mx_inline_x##FCN, #FCN); \
+  return do_mm_binary_op<T::element_type, T::element_type, T::element_type> (a, b, mx_inline_x##FCN, #FCN); \
 }
 
 #define MINMAX_FCNS(T, S) \